WinAPI在dll中创建窗口

WinAPI create window in dll

本文关键字:创建 窗口 dll WinAPI      更新时间:2023-10-16

我在游戏进程中注入了一个dll,然后dll创建钩子,它创建了一个新线程来处理windows事件。

线程功能:

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::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 %dn", 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 %dn", 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 %dn", 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;
}

GetLastError的输出为:

GetLastError 0

GetLastError 127

GetLastError 127

我不明白为什么没有创建这个标签和按钮。窗口总是创建的,排除任何问题。有什么帮助吗?

首先,正如注释中所述,除非前一个函数实际失败,否则GetLastError的结果是没有意义的。因此,您必须首先检查是否为m_hLInfo == NULL(不过,我想是这样)。

关于实际问题:在我看来,您的代码使用的是Windows API的Unicode-version,但提供的是ANSI字符串。

正确创建窗口的原因是您明确调用了CreateWindowExA(注意A),这是该函数的ANSI版本。对于按钮和您称之为CreateWindowEx的标签,头文件的#define'd为CreateWindowExW,即Unicode版本。但是你的类名("STATIC""BUTTON")不是Unicode!(因此,Windows试图创建具有mojibake类名的窗口,这当然会非常失败。)

因此,您可以在任何地方将CreateWindowEx更改为CreateWindowExA,或者更好地在任何地方使用正确的Unicode字符串:从CreateWindowExA中删除A,并在为WinAPI函数提供的所有字符串之前加上L,例如L"BUTTON"。(或者,如果您不确定是否始终处于Unicode编译器环境中,则可以使用_T宏,例如_T("BUTTON")。)

进一步阅读:
Wikibooks文章
MSDN文章