2017-12-16 75 views
1
#include <stdio.h> 
#include <stdbool.h> 
#include <Windows.h> 

HWND WindowHandle; 
HINSTANCE Instance; 
const wchar_t WindowClassName[] = L"Temp Projcet"; 

LRESULT CALLBACK WindowProc(HWND _windowHandle, UINT _msg, WPARAM _param, LPARAM _param1) { 
    switch (_msg) { 
    case WM_PAINT: { 
     PAINTSTRUCT ps; 
     HDC hdc = BeginPaint(WindowHandle, &ps); 
     FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1)); 
     EndPaint(WindowHandle, &ps); 
    } break; 
    case WM_CLOSE: { 
     if (IDOK == MessageBoxW(WindowHandle, L"Quit?", L"My application", MB_OKCANCEL)) { 
      DestroyWindow(WindowHandle); 
     } 
     return false; 
    } break; 
    case WM_DESTROY: { 
     PostQuitMessage(0); 
    } break; 
    default: 
     break; 
    } 
    return DefWindowProcW(WindowHandle, _msg, _param, _param1); 
} 

ATOM RegisterWindowClass(void) { 
    WNDCLASS wc = { 0 }; 
    wc.lpfnWndProc = WindowProc; 
    wc.hInstance = Instance; 
    wc.lpszClassName = WindowClassName; 
    return RegisterClassW(&wc); 
} 

int APIENTRY wWinMain(HINSTANCE _instance, HINSTANCE _prevInstance, PWSTR _cmdLine, int _cmdShow) { 
    Instance = _instance; 
    RegisterWindowClass(); 

    WindowHandle = CreateWindowExW(
     0, 
     WindowClassName, 
     L"This a window", 
     WS_OVERLAPPEDWINDOW, 
     CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
     NULL, 
     NULL, 
     Instance, 
     NULL 
    ); 

    DWORD err = GetLastError(); 
    // Why error 1400 Invalid window handle? 

    MSG msg = { 0 }; 
    while (GetMessageW(&msg, WindowHandle, 0, 0)) { 
     TranslateMessage(&msg); 
     DispatchMessageW(&msg); 
    } 

    return 0; 
} 

왜 창을 만들 때 1400 개의 잘못된 핸들을 반환합니까? 그럴 필요 없나요? 윈도우 생성 함수에는 창 핸들이 없습니다. 어떻게 그것이 잘못된 핸들이 될 수 있습니까? 나는 오랜 시간 동안 검색 엔진을 통해 검색했지만 아직도이 문제를 해결할 수 없습니까? CreateWindowExW()가 1400을 반환하는 이유는 무엇입니까? 라인 여기에 실제로 오류가되어있는 경우, 테스트하지 않았습니다왜 오류 1400 잘못된 창 핸들입니까?

DWORD err = GetLastError(); 

(44)

+0

디버거를 통해 실행 해 보셨습니까? –

+0

다시 할 수 있습니다. 'RegisterWindowClass'는 성공했지만'CreateWindowExW'는 실제로'NULL'을 리턴합니다. – zett42

+0

그냥 버그 일 뿐이므로 _windowHandle 매개 변수를 사용해야합니다. 전역 변수는 나중에 CreateWindowEx가 반환 될 때까지 값을 가져 오지 않습니다. 현재 WM_NCCREATE의 처리가 엉망이되어 버렸습니다. –

답변

0

에서 코드입니다. GetLastError를 호출하기 전에 CreateWindowEx에서 가져온 핸들을 테스트해야합니다. 그렇지 않은 경우, 이전의 관련이없는 에러 또는 임의의 값을 돌려줍니다.

+0

WindowHandle이 NULL입니다. – TangJinJian

+0

코드에서 테스트하지 않습니다. –

0

CreateWindow가 실패한 경우에만 (즉, CreateWindow가 NULL을 반환하는 경우) GetLastError를 호출하십시오.

대다수의 성공적인 Windows API 호출 후에 마지막 오류 값이 지정되지 않은 경우 GetLastError를 호출하기 전에 반환 값을 확인해야합니다.

+0

CreateWindowExW()는 NULL을 반환합니다. – TangJinJian

2

반환 값이 CreateWindowEx으로 설정되기 전에 윈도우 프로 시저에서 WindowHandle을 사용하고 있습니다. 그 중 CreateWindowEx 호출의 일부는 WM_NCCREATEWM_CREATE으로 윈도우 프로 시저를 호출합니다. 창 프로시 저는 그 시점에서 null 핸들이있는 DefWindowProc을 호출합니다.

여기서 간단한 해결책은 WindowHandle 글로벌 대신 _windowHandle 매개 변수를 사용하는 것입니다.

창을 표시하려면 ShowWindow으로 전화해야합니다. 또한 게시 한 종료 메시지는 해당 창과 관련이 없으므로 GetMessage 호출은 메시지를 검색하지 않으며 응용 프로그램이 종료되지 않습니다.

+1

명시 적으로 쓰려면'GetMessage'에 대한 두 번째 인수는 윈도우 메시지뿐만 아니라 WM_QUIT와 같은 스레드 메시지를 처리하는 데 'NULL'이어야합니다. – zett42