VS2019 i problem z TCHAR

0

Staram się użyć w programie struktury, kłopot mam z VisualStudio19.

static const struct {
	TCHAR *pszText;
	int cx;
}
columnMap[] = {
	{ _T("Tytul1"), 150 },
	{ _T("Tytul2"), 60  },
	{ _T("Tytul3"), 120 },
	{ 0 }
};

static const struct {
	TCHAR *pszName;
	TCHAR *pszPriority;
	int iProgress;
}
taskMap[] = {
	{ _T("Zmienna1"),         _T("Zmienna2"),   15 },
	{ 0 }
};

Błąd który otrzymuje:
Error (active) E0144 a value of type "const wchar_t *" cannot be used to initialize an entity of type "TCHAR *" Przyklad E:\Programowanie\VisualStudio\VC2019-Projekty\Przyklad\Source\WinApplication.cpp 43

Nie mam problemu z tym kawałkiem kodu w CodeBuilder.
Mam wrażenie że muszę coś ustawić we właściwościach projektu.
Zmieniałem Character Set z 3 opcjami, ale nie zaskoczyło.

Cała moja piaskownica:

#include <Windows.h>

#include <tchar.h>
#include <commctrl.h>
#include <string.h>
#include <stdio.h>

#include <fstream>
#include <iostream>

using namespace std;
/*
static struct {
    TCHAR* pszText;
    int cx;
}
columnMap[] = {
    { _T("Tytul1"), 150 },
    { _T("Tytul2"), 60  },
    { _T("Tytul3"), 120 },
    { 0 }
};

static const struct {
    TCHAR* pszName;
    TCHAR* pszPriority;
    int iProgress;
}
taskMap[] = {
    { _T("Zmienna1"),         _T("Zmienna2"),   15 },
    { 0 }
};
*/
class Plik
{
private:
    fstream fileStream;
    string SciezkaDoPliku;
    streampos RozmiarPliku;
    streampos WczytanychBajtow;

public:

    Plik(const std::string _SciezkaDoPliku)
        : SciezkaDoPliku{ _SciezkaDoPliku },
        RozmiarPliku{ 0 },
        WczytanychBajtow{ 0 }
    {
        this->SciezkaDoPliku = _SciezkaDoPliku;
        fstream fileStream(SciezkaDoPliku.c_str());
    }

    ~Plik() {
        if (fileStream.is_open()) {
            Close();
        }
    }

    void Close()  //Zamkniecie lacza z plikiem.
    {
        if (fileStream.is_open())
            fileStream.clear();
        fileStream.close();
    }

    int Open(HWND hwnd)
    {
        fileStream.open(SciezkaDoPliku.c_str(), ios::in | ios::binary | ios::ate);
        if (!fileStream.is_open()) {
            SetWindowText(hwnd, TEXT("Nie udalo sie otworzyc pliku.\r\n"));
            return 1;
        }
        return 0;
    }

};


static HWND button;
static HWND textBoxOutput;

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR cmdLine, int nCmdShow)
{
    HWND hMainWindow;
    WNDCLASS wc = {};
    wc.lpfnWndProc = WindowProc;
    wc.lpszClassName = L"Main window class";
    wc.hInstance = hInstance;
    RegisterClass(&wc);


    hMainWindow = CreateWindow(wc.lpszClassName, L"Append text main window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 400, NULL, NULL, hInstance, NULL);

    if (hMainWindow == NULL) return 1;

    button = CreateWindowEx(WS_EX_CLIENTEDGE, L"Button", L"Append", WS_CHILD | WS_VISIBLE | ES_CENTER, 10, 41, 75, 30, hMainWindow, NULL, NULL, NULL);

    textBoxOutput = CreateWindowEx(WS_EX_CLIENTEDGE, L"Edit", TEXT(""), WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_AUTOVSCROLL | ES_MULTILINE | ES_READONLY, 10, 81, 450, 150, hMainWindow, NULL, NULL, NULL);


    ShowWindow(hMainWindow, SW_SHOW);

    MSG msg = { };

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_COMMAND:
        if ((HWND)lParam == button)
        {
            Plik p1("d:\\test1.txt");
            p1.Open(textBoxOutput);
        }
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

Zakomentowałem wstawione struktury które mi nie działają.

0

https://stackoverflow.com/questions/12446404/tchar-and-unresolved-external-symbol-lnk2019-error-in-c-program

Chyba tam masz odpowiedź. Z tymi Windowsowymi typami są zawsze jakieś jaja.

2

Windowsowe typy nie mają tu nic do rzeczy.

Dowód: takie coś się również nie skompiluje, z takiego samego powodu:

static struct {
    char* pszText;
    int cx;
}
columnMap[] = {
    { "Tytul1", 150 },
    { "Tytul2", 60  },
    { "Tytul3", 120 },
    { 0 }
};

E0144 a value of type "const char *" cannot be used to initialize an entity of type "char *"

Nie mam problemu z tym kawałkiem kodu w CodeBuilder.

Pewnie kompilowałeś jako C a nie C++.

2
Azarien napisał(a):

Dowód: takie coś się również nie skompiluje, z takiego samego powodu:

E0144 a value of type "const char *" cannot be used to initialize an entity of type "char *"

Nie mam problemu z tym kawałkiem kodu w CodeBuilder.

Pewnie kompilowałeś jako C a nie C++.

Dodam, ze zupełnie zbędne i niczemu nie służące "hackerskie" jednolinijkowe zapisy itd (dla mnie w tym przypadku anty-czytelne)...
Żadnego problemu by nie było, gdyby były dwie fazy

  • deklaracja struktury ŚREDNIK
  • definicja i inicjalizacja zmiennej

Ale to takie "banalne" ...

3
idepozapalki napisał(a):

Dodanie const w tym miejscu powoduje, że program nie chce się skompilować i aplikacja nie działa.

Wyjaśnij. Bo to co próbujesz zrobić, a co można uprościć do banalnego przykładu

char *napis = "Test";

Jest dozwolone w C, ale nie jest dozwolone w C++.

C++ wymaga const:

const char *napis = "Test";

To jest przyczyna twojego problemu.

1

Jak masz problem z ListView to wypadałoby dodać kod. Jeśli chodzi o wskaźnik pszText w LVITEM lub argument w ListView_SetItemText, to radzisz sobie użyciem const_cast. Taka przypadłość winapi, wynikająca z tego, że LVITEM używana jest do przesyłania danych zarówno do (tu by mogło być const), jak i z (a tu nie może być const) ListView.

1 użytkowników online, w tym zalogowanych: 0, gości: 1