简体   繁体   English

WinAPI在DLL中创建窗口

[英]WinAPI create window in dll

I injected a dll into the game process, and then dll create hook which creates, a new thread to handle the windows event. 我向游戏进程中注入了一个dll,然后dll create hook创建了一个新线程来处理Windows事件。

Thread function: 线程功能:

void CFile::winThread(void *pData)
{
    CFile *pThis = reinterpret_cast<CFile*>(pData);

    // Common controls init
    INITCOMMONCONTROLSEX iCC;
    iCC.dwSize = sizeof(INITCOMMONCONTROLSEX);
    iCC.dwICC = ICC_BAR_CLASSES;

    InitCommonControlsEx(&iCC);

    pThis->m_pConnect = new WinConnect(300, 180);
    pThis->m_pConnect->setText("Connecting");
    pThis->m_pConnect->show();

    MSG message;
    while (GetMessage(&message, 0, 0, 0))
    {
        TranslateMessage(&message);
        DispatchMessage(&message);
    }

    tthread::mutex _mutex;
    _mutex.lock();
    pThis->m_bIsFinished = true;
    _mutex.unlock();
}

WinConnect.cpp WinConnect.cpp

WinConnect::WinConnect(int width, int height)
{
    if (registerWin())
    {
        int screenWidth = GetSystemMetrics(SM_CXSCREEN);
        int screenHeight = GetSystemMetrics(SM_CYSCREEN);
        int x = (screenWidth / 2) - (width / 2);
        int y = (screenHeight / 2) - (height / 2);

        m_hWin = CreateWindowExA(WS_EX_CLIENTEDGE, winNameConnect, "Test Window",
            WS_POPUP | WS_BORDER | WS_CAPTION,
            x, y + 200, width, height, NULL, NULL, GetModuleHandle(NULL), NULL);

        printf("GetLastError %d\n", GetLastError());

        if (m_hWin)
        {
            RECT size;
            GetClientRect(m_hWin, &size);

            int winH = size.bottom - size.top;
            int winW = size.right - size.left;
            int buttonW = winW / 2;

            m_hLInfo = CreateWindowEx(0, "STATIC", "",
            WS_VISIBLE | WS_CHILD | SS_CENTER | SS_CENTERIMAGE,
            7, 7, winW - 14, winH - 41, m_hWin, NULL, GetModuleHandle(NULL), NULL);

            printf("GetLastError %d\n", GetLastError());

            // 9 pix odstep height
            m_hBCancel = CreateWindowEx(0, "BUTTON", "Cancel",
                WS_VISIBLE | WS_CHILD | SS_CENTER,
                buttonW / 2, winH - 30, buttonW, 25, m_hWin, NULL, GetModuleHandle(NULL), NULL);

            printf("GetLastError %d\n", GetLastError());
        }       
    }
}

bool WinConnect::registerWin()
{
    WNDCLASSEX winClass;

    winClass.hInstance = GetModuleHandle(NULL);
    winClass.lpszClassName = winNameConnect;
    winClass.lpfnWndProc = wndProc;
    winClass.style = CS_DBLCLKS;
    winClass.cbSize = sizeof(WNDCLASSEX);
    winClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    winClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    winClass.lpszMenuName = NULL;
    winClass.cbClsExtra = 0;
    winClass.cbWndExtra = 0;
    winClass.hbrBackground = (HBRUSH)COLOR_BACKGROUND;

    if (!RegisterClassEx(&winClass))
        return false;

    return true;
}

The output of GetLastError is: GetLastError的输出是:

GetLastError 0 GetLastError 0

GetLastError 127 GetLastError 127

GetLastError 127 GetLastError 127

I can't figure out why this label and button are not created. 我不知道为什么不创建此标签和按钮。 Window always is created, witchout any problem. 窗口总是被创建,避免任何问题。 Any help? 有什么帮助吗?

Firstly, as stated in the comments, GetLastError 's result is meaningless unless the previous function actually failed. 首先,如注释中所述,除非先前的函数实际失败,否则GetLastError的结果是没有意义的。 So you would have to check for instance whether m_hLInfo == NULL first (which I guess it is, though). 因此,您必须首先检查m_hLInfo == NULL是否为m_hLInfo == NULL (不过我想是的)。

About the actual problem: It looks to me like your code is using the Unicode-version of the Windows API but feeding it ANSI strings. 关于实际问题:在我看来,您的代码正在使用Windows API的Unicode版本,但将其提供给ANSI字符串。

The reason why the window is created correctly is that you explicitely call CreateWindowExA (notice the A ) which is the ANSI-version of the function. 正确创建窗口的原因是,您明确调用了函数的ANSI版本的CreateWindowExA (注意A )。 For the button and the label you call CreateWindowEx which your header files have #define 'd as CreateWindowExW , the Unicode-version. 对于按钮和标签,您调用CreateWindowEx ,其头文件已# #defineCreateWindowExW ,即Unicode版本。 But your class names ( "STATIC" and "BUTTON" ) are not Unicode, though! 但是,您的类名( "STATIC""BUTTON" )却不是Unicode! (So Windows tries to create windows with mojibake classnames, which will of course fail horribly.) (因此Windows尝试使用mojibake类名创建窗口,这当然会严重失败。)

So you could either change CreateWindowEx to CreateWindowExA everywhere, or - better - use proper Unicode strings everywhere: Remove the A from CreateWindowExA and prepend all strings you feed WinAPI function with L , eg L"BUTTON" . 因此,您可以在任何地方都将CreateWindowEx更改为CreateWindowExA ,或者-更好地-在各处使用正确的Unicode字符串:从CreateWindowExA删除A ,并在所有使用L提供给WinAPI函数的字符串之前加上L ,例如L"BUTTON" (Or, if you are not sure that you will always be in a Unicode compiler environment, you can use the _T macro, eg _T("BUTTON") .) (或者,如果不确定您将始终处于Unicode编译器环境中,则可以使用_T宏,例如_T("BUTTON") 。)

Further reading: 进一步阅读:
Wikibooks article Wikibooks文章
MSDN article MSDN文章

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM