2

我用 C++ 编程的时间不长,但需要为我的学校制作一个 Win32 应用程序。老师在信息方面帮助了我很多,但经过几天的尝试,我仍然卡住了。

错误:

error C2440: '=' : cannot convert from 'const char [11]' to 'LPCWSTR'
error C2664: 'CreateWindowExW' : cannot convert parameter 2 from 'const char [11]' to 'LPCWSTR'
error C2664: 'TextOutW' : cannot convert parameter 4 from 'char *' to 'LPCWSTR'
IntelliSense: argument of type "char *" is incompatible with parameter of type "LPCWSTR"

不知道其他所有内容是否正确,但我现在只收到这 4 个错误

cpp文件:

    /* Hoofdstuk 10, User Interface */
#include "Callback_NYCM.h"

// UI
int WINAPI WinMain(HINSTANCE thisInstance,HINSTANCE prevInstance,LPSTR lpCmdLine,int nShowCmd) 
{ 
    PAINTSTRUCT ps;
    HDC hdc;
    MSG msg;
    HWND hwnd;
    WNDCLASSEX wndclassex; //struct_WNDCLASSEX via windows.h    

    // toekenning
    wndclassex.cbSize = sizeof(WNDCLASSEX); 
    wndclassex.style = CS_HREDRAW | CS_VREDRAW;
    wndclassex.lpfnWndProc = WndProc;
    wndclassex.cbClsExtra = 0;
    wndclassex.cbWndExtra = 0;
    wndclassex.hInstance = thisInstance;
    wndclassex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndclassex.hCursor = LoadCursor(thisInstance,IDC_ARROW);  
    wndclassex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wndclassex.lpszMenuName = NULL;  
    wndclassex.lpszClassName = "WNDCLASSEX"; 
    wndclassex.hIconSm = LoadIcon(NULL, IDI_APPLICATION); 

    // functie aanroep
    RegisterClassEx(&wndclassex);

// IfThen -> CreateWindows
    if(!(hwnd = CreateWindowEx(NULL,"WNDCLASSEX","Hoofdstuk 10",WS_OVERLAPPEDWINDOW 
        | WS_VISIBLE,50,50,650,300,NULL,NULL,thisInstance,NULL)))  
    {  
        return 0; 
    } 
// logische structuur
while(GetMessage(&msg, NULL, 0, 0))  
{  
    if(msg.message == WM_QUIT)    
        break;   
    TranslateMessage(&msg);   
    DispatchMessage(&msg);  
}  
return (int) msg.wParam; 
};

头文件:

 /*Hoofdstuk 10, Deelnemer.h*/ 
//Declaratie 
class Deelnemer 
{ 
private: 
    char* nm; 
public: 

//Constructor 
Deelnemer(){
}
    //Methoden = prototype 
    void Deelnemer::Invoeren();
    char* Deelnemer::WeergevenNaam();
};  
//Implemenmtatie.Invoeren 
void Deelnemer::Invoeren() 
{
    nm = "Roy"; 
}  
//.Weergeven 
char* Deelnemer::WeergevenNaam()
{ 
    return nm;
}

回调_NYCM.h:

    /*Hoofdstuk 10, Callback_NYCM*/
#include "Windows.h"
#include "Deelnemer.h"  

// prototype
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam); 

//Implementatie 
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam) 
{  
    //Constructie  
    PAINTSTRUCT ps;
    HDC hdc;
    MSG msg;
    WNDCLASSEX wndclassex;
    // HWND hwnd;
    Deelnemer deelnemer1; 


    //UI   
    switch(message)
    {
    case WM_PAINT:    
        {     
            //Functieaanroep.Initialisatie     
            deelnemer1.Invoeren();          
            //.TextOut  
            TextOut(hdc,50,50,deelnemer1.WeergevenNaam(),     
            strlen(deelnemer1.WeergevenNaam()));     
            EndPaint(hwnd,&ps);     
            return 0;   
        }    
        break;
        case WM_DESTROY:    
            {     
                PostQuitMessage(0);     
                return 0;    
            }    
            break;   
        default:    
            {     
                return DefWindowProc(hwnd,message,wparam,lparam);    
            }    
            break; 
    }
    return 0;
}

我认为我的构造函数或类似的东西是错误的,我的 char* Deelnemer::WeergevenNaam() 的返回值

有人可以解释一下我的代码有什么问题,以便我知道如何让它工作吗?

更新:

更新您的应用程序需要始终使用 UNICODE 字符串文字,即 L"MyString" 而不是 "MyString"。您还需要使用 WCHAR/wchar_t 代替 char

但是我如何用我的代码做到这一点,有人可以帮忙吗?

更新 2:

这解决了很多错误!

但是我在这部分还有一些错误

Deelnemer deelnemer1;   
    switch(message)
    {
    case WM_PAINT:    
        {     
            //Functieaanroep.Initialisatie     
            deelnemer1.Invoeren();          
            //.TextOut  
        TextOut(hdc,50,50,deelnemer1.WeergevenNaam(),     
            strlen(deelnemer1.WeergevenNaam()));     
            EndPaint(hwnd,&ps);     
            return 0;   
        }

所以错误在线:deelnemer1.WeergevenNaam()

-TextOutW' : 无法将参数 4 从 'char *' 转换为 'LPCWSTR'

-IntelliSense:“char *”类型的参数与“LPCWSTR”类型的参数不兼容

更新 3:

经过一些测试,我找到了一个解决方案(就像你们在下面所说的那样)但现在我只剩下这个了: TextOut (hdc,50,50,deelnemer1.WeergevenNaam(), //在 deelnemer1.weergevenNaam()
上,错误 C2664: 'TextOutW' : cannot convert parameter 4 from 'const char *'到“LPCWSTR”

4

5 回答 5

6

您的代码被编写为编译为 ANSI,但您的解决方案设置包括_UNICODE/ UNICODE。您可以通过将Character Set(在Configuration Properties的General节点上)从Use Unicode Character Set更改为Use Multi-Byte Character Set来设置您的解决方案以使用 ANSI 编码,或者更新您的应用程序代码(建议使用后者)。

更新您的应用程序需要在整个过程中使用 UNICODE 字符串文字,即,L"MyString"而不是"MyString". 您还需要使用WCHAR/wchar_t代替char(如果适用)并调用 Windows API 的广泛版本。对于许多 API 调用,存在一个W以结尾结尾的宽版本,例如CreateWindowExW. 如果您使用的是标准 C++ 库,您还需要确保在需要字符编码的地方使用 UNICODE 变体(例如std::wstring,而不是std::string)。可以在 Visual C++ 中的文本和字符串中找到更多信息。

关于这里发生的事情的更多背景信息:Windows API 和 Microsoft 的 CRT 实现可用于编译使用 ANSI/多字节字符集或 UNICODE 字符集的代码。_UNICODE为了支持这两种字符编码,C/C++ 预处理器根据是否定义了和UNICODE预处理器符号,将相应的字符类型和 API 调用替换为特定的实现。

例如,调用CreateWindowEx扩展为CreateWindowExACreateWindowExW。两种实现都有不同的字符串参数参数类型(char*wchar_t*分别)。要使用 ANSI/多字节编码,调用将是CreateWindowExA(NULL,"WNDCLASSEX",...). 对于 UNICODE,它看起来像CreateWindowExW(NULL,L"WNDCLASSEX",...).

要查看预处理器完成后代码的样子,您可以使用/P/E编译器开关(假设您使用的是 Microsoft 编译器)。

注意:不要忘记阅读每个软件开发人员绝对、肯定必须了解 Unicode 和字符集的绝对最低要求(没有借口!)

于 2013-08-27T16:36:50.610 回答
2

简单的答案 - 没有解释为什么

将带引号的字符串更改为 L"foo"

将 char 更改为 wchar_t

于 2013-08-27T17:08:51.890 回答
0

LPCWSTR -> 指向常量宽字符串的长指针。

您的所有错误消息都简化为某种形式的 char[XX] 与 wchar_t[XX] 的类型不同。

Microsoft 的 Win32 API 旨在使用 ANSI 字符串、char 或宽字符串 wchar_t 进行编译。这就是为什么许多 Win32 函数有两个签名,一个以 A 结尾,另一个以 W 结尾的原因。

例子:

CreateWindowExW
CreateWindowExA

CreateWindowEx - 根据您的构建配置扩展为上述签名之一的宏。如果您定义 UNICODE 或 _UNICODE 它将扩展到 W 版本。

通常在 Win32 中编程时使用宏,并使用 _T 宏包装所有字符串文字。在定义字符串的字符数组时,您需要使用 LPCTSTR 和 LPTSTR。这些也是宏,将根据您的构建设置扩展为 char * 或 wchar_t *。

于 2013-08-27T17:04:08.460 回答
0

我有它的工作。使用 wchar_t * 和 L"string"。我的代码的问题更多是结构,因为复制/粘贴到新项目解决了我的错误。多谢你们!

于 2013-09-01T18:48:14.743 回答
0

通过在 中选择“未设置” Character SetProject > Property > Configuration Properties > General我能够删除错误C2440C2264.

于 2015-10-30T17:32:41.427 回答