2013-12-19 6 views
1

Я экспериментировал с WINAPI, пытаясь его изучить, но созданное мной окно закрывается мгновенно. Как вы видите, когда нажата клавиша W или нажата левая кнопка, она закроет программу, но при ее запуске без нажатия кнопок она все равно закрывается.Окно WinAPI закрывается мгновенно

#include <windows.h> 
#include <windowsx.h> 


// the WindowProc function prototype 
LRESULT CALLBACK WindowProc(HWND hWnd, 
    UINT message, 
    WPARAM wParam, 
    LPARAM lParam); 

// the entry point for any Windows program 
int WINAPI WinMain(HINSTANCE hInstance, 
    HINSTANCE hPrevInstance, 
    LPSTR lpCmdLine, 
    int nCmdShow) 
{ 
    // the handle for the window, filled by a function 
    HWND hWnd; 
    // this struct holds information for the window class 
    WNDCLASSEX wc; 

    // clear out the window class for use 
    ZeroMemory(&wc, sizeof(WNDCLASSEX)); 

    // fill in the struct with the needed information 
    wc.cbSize = sizeof(WNDCLASSEX); 
    wc.style = CS_HREDRAW | CS_VREDRAW; 
    wc.lpfnWndProc = WindowProc; 
    wc.hInstance = hInstance; 
    wc.hCursor = LoadCursor(NULL, IDC_ARROW); 
    wc.hbrBackground = (HBRUSH)COLOR_WINDOW; 
    wc.lpszClassName = L"WindowClass1"; 

    // register the window class 
    RegisterClassEx(&wc); 

    // create the window and use the result as the handle 
    hWnd = CreateWindowEx(NULL, 
     L"WindowClass1", // name of the window class 
     L"Game", // title of the window 
     WS_OVERLAPPEDWINDOW, // window style 
     1, // x-position of the window 
     1, // y-position of the window 
     1800, // width of the window 
     1000, // height of the window 
     NULL, // we have no parent window, NULL 
     NULL, // we aren't using menus, NULL 
     hInstance, // application handle 
     NULL); // used with multiple windows, NULL 

    // display the window on the screen 
    ShowWindow(hWnd, nCmdShow); 

    // enter the main loop: 

    // this struct holds Windows event messages 
    MSG msg; 

    // wait for the next message in the queue, store the result in 'msg' 
    while (GetMessage(&msg, NULL, 0, 0)) 
    { 
     // translate keystroke messages into the right format 
     TranslateMessage(&msg); 

     // send the message to the WindowProc function 
     DispatchMessage(&msg); 
    } 

    // return this part of the WM_QUIT message to Windows 
    return msg.wParam; 
} 

// this is the main message handler for the program 
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    // sort through and find what code to run for the message given 
    switch (message) 
    { 
     // this message is read when the window is closed 

    case WM_MOUSEMOVE: 
    { 

     // Retrieve mouse screen position 
     int x = (short)LOWORD(lParam); 
     int y = (short)HIWORD(lParam); 

     // Check to see if the left button is held down: 
     bool leftButtonDown = wParam & MK_LBUTTON; 

     // Check if right button down: 
     bool rightButtonDown = wParam & MK_RBUTTON; 

     if (leftButtonDown == true) 
     { 
      //left click 
      //example lets close the program when press w 
      PostQuitMessage(0); 
      return 0; 
     } 


    } 

    case WM_KEYDOWN: 
    {       
     switch (wParam) 
     { 
     case 'W': 

      //w pressed 
      //example lets close the program when press w 
      PostQuitMessage(0); 
      return 0; 
     } 
    } 

    case WM_DESTROY: 
    { 
     // close the application entirely 
     PostQuitMessage(0); 
     return 0; 
    } 
    default: 
     break; 
    } 

    // Handle any messages the switch statement didn't 
    return DefWindowProc(hWnd, message, wParam, lParam); 
} 
+0

Боковое примечание. Некоторая комментировка неверна. – Mackenzie

+0

Комментарий стиля: напишите 'if (condition)', а не 'if (condition == true)'. – Roddy

+0

Попробуйте удалить это: 'return DefWindowProc (hWnd, message, wParam, lParam);' Разве это имеет значение? – kvr

ответ

3

Там нет в вашем switch заявлении нет break.

Вы в конечном итоге exetuting

PostQuitMessage(0); 

Вы могли бы сделать что-то вроде этого:

case WM_FOO: 
{ 
    if (bar) { 
     return 0; 
    } 
    break; 
} 
5

Вы пропустили некоторые break заявления в коммутаторе, так, например, если вы получаете сообщение WM_MOUSEMOVE и leftButtonDown != true, выполнение будет проходить до WM_KEYDOWN и т. д.

В конце концов вы доберетесь до case WM_DESTROY:, который будет Post вы прекрасный QuitMessage.

Как в стороне, это было бы очень легко обнаружить, выполнив инструкцию-by-statement в отладчике.

+0

Я положил перерывы, но он все равно закрывается мгновенно. – Mackenzie

+0

@MackenzieGoodwin Обновите код в вопросе. – manuell

+0

@icabod Все хорошо, я переустановил драйверы для своей дорожки. Спасибо всем за помощь! – Mackenzie

0

Не обнаруживайте кликов через сообщение WM_MOUSEMOVE, вместо этого используйте WM_MOUSEDOWN.

Проблема в том, что ваш код, вероятно, запущен вами, нажав на что-то, поэтому, когда ваше окно получает свое первое сообщение WM_MOUSEMOVE, кнопка по-прежнему нажата. Код работает много быстрее, чем пальцы.

Смежные вопросы