2016-04-09 9 views
2

Ich habe eine DLL in den Spielvorgang injiziert, und dann erstellen dll Hook, die erstellt, ein neuer Thread das Windows-Ereignis zu behandeln.WinAPI create window in dll

Thread-Funktion:

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 %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; 
} 

Der Ausgang des GetLastError ist:

GetLastError 0

GetLastError 127

GetLastError 127

ich nicht herausfinden können, warum dieses Label und Button werden nicht erstellt. Fenster wird immer erstellt, ohne irgendein Problem. Irgendeine Hilfe?

+0

Gebrochene Fehlerbehandlung der erste offensichtliche Fehler, rufen Sie GetLastError() nur dann auf, wenn die winapi-Funktion fehlgeschlagen ist. –

+0

'GetLastError' gibt nur den letzten Fehler zurück. Es muss tatsächlich einen Fehler geben, damit 'GetLastError' einen nützlichen Wert zurückgibt. Wie eine bestimmte Funktion einen Fehler anzeigt, hängt von der Funktion ab. – Neil

+0

Also keine Ahnung, wie kann ich den wahren Grund überprüfen? –

Antwort

0

Erstens, wie in den Kommentaren angegeben, GetLastError ist das Ergebnis bedeutungslos, wenn die vorherige Funktion tatsächlich fehlgeschlagen ist. So müssten Sie zum Beispiel prüfen, ob m_hLInfo == NULL zuerst (was ich denke, es ist, obwohl).

Über das eigentliche Problem: Es sieht für mich aus wie Ihr Code die Unicode-Version der Windows-API verwendet, aber es ANSI-Zeichenfolgen einspeist.

Der Grund, warum das Fenster korrekt erstellt wird, ist, dass Sie explizit CreateWindowExA aufrufen (beachten Sie die A), die die ANSI-Version der Funktion ist. Für die Schaltfläche und das Label rufen Sie CreateWindowEx an, die Ihre Header-Dateien #define 'CreateWindowExW, die Unicode-Version haben. Aber Ihre Klassennamen ("STATIC" und "BUTTON") sind nicht Unicode, obwohl! (. So versucht Windows-Fenster mit Mojibake Klassennamen zu schaffen, was natürlich nicht schrecklich)

So könnte man entweder CreateWindowEx-CreateWindowExA überall ändern, oder - besser - für die richtigen Unicode-Strings überall verwenden: Entfernen Sie die A von CreateWindowExA und prepend Alle Strings, die Sie füttern, WinAPI-Funktion mit L, z L"BUTTON". (Oder, wenn Sie nicht sicher sind, dass Sie immer in einer Unicode-Compiler-Umgebung sein werden, können Sie das _T Makro verwenden, zB _T("BUTTON").)

Weiterführende Literatur:
Wikibooks article
MSDN article

+0

Projekt ist auf ANSI eingestellt. –