2013-08-18 2 views
1

Я пытаюсь написать программу для нескольких окон. В этой программе, когда пользователь щелкнул левой кнопкой мыши по одному окну, он должен получить сообщение, в которое было нажато окно. Вот мой код:win32-программа для нескольких окон

#include<Windows.h> 
// Store handles to the main window and application instance globally. 
HWND ghFirstWnd =0; 
HWND ghSecondWnd=0; 
HWND ghThirdWnd=0; 
HINSTANCE ghAppInst=0; 
//======================================================================================== 
// WINDOW 1 
// Step 1: Define and implement the window procedure. 
LRESULT CALLBACK 
WndProc1(HWND hWnd,UINT msg,WPARAM wParam, LPARAM lParam) 
{ 
    switch(msg) 
    { 
    // Handle left mouse button click message. 
    case WM_LBUTTONDOWN: 
     MessageBox(0,L"first window ",L"MSG",MB_OK); 
     return 0; 
    // Handle key down message. 
    case WM_KEYDOWN: 
     if(wParam==VK_ESCAPE) 
      if(MessageBox(hWnd,L"sure ??",L"confirmation",MB_YESNO)==IDYES) 
       DestroyWindow(ghFirstWnd); 
     return 0; 
    // Handle destroy window message. 
    case WM_DESTROY: 
     PostQuitMessage(0); 
     return 0; 
    } 
    return DefWindowProc(hWnd,msg,wParam,lParam); 
} 
//======================================================================================== 
// WINDOW 2 
//======================================================================================== 
LRESULT CALLBACK 
WndProc2(HWND hWnd,UINT msg, WPARAM wParam,LPARAM lParam) 
{ 
    switch(msg) 
    { 
    case WM_LBUTTONDOWN: 
     MessageBox(0,L"second window",L"msg",MB_OK); 
     return 0; 
    } 
    return DefWindowProc(hWnd,msg,wParam,lParam); 
} 
//======================================================================================== 
// WINDOW 3 
//======================================================================================== 
LRESULT CALLBACK 
WndProc3(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) 
{ 
    switch(msg) 
    { 
    case WM_LBUTTONDOWN: 
     MessageBox(0,L"third window",L"msg",MB_OK); 
     return 0; 
    } 
    return DefWindowProc(hWnd,msg,wParam,lParam); 
} 
// WinMain: Entry point for windows application. 
int WINAPI 
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR cmdLine,int showCmd) 
{ 
    // Save handle to application instance. 
    ghAppInst=hInstance; 
    // Step 2: Fill out a WNDCLASS instance. 
    WNDCLASS wc1; 
    wc1.style =CS_HREDRAW|CS_VREDRAW; 
    wc1.lpfnWndProc =WndProc1; 
    wc1.cbClsExtra=0; 
    wc1.cbWndExtra=0; 
    wc1.hInstance=ghAppInst; 
    wc1.hIcon=::LoadIcon(0,IDI_APPLICATION); 
    wc1.hCursor=::LoadCursor(0,IDC_ARROW); 
    wc1.hbrBackground=(HBRUSH)::GetStockObject(WHITE_BRUSH); 
    wc1.lpszMenuName=0; 
    wc1.lpszClassName=L"first class"; 
    // Window 2 
    WNDCLASS wc2; 
    wc2.style=CS_HREDRAW|CS_VREDRAW; 
    wc2.lpfnWndProc=WndProc2; 
    wc2.cbClsExtra=0; 
    wc2.cbWndExtra=0; 
    wc2.hInstance=ghAppInst; 
    wc2.hIcon=::LoadIcon(0,IDI_APPLICATION); 
    wc2.hCursor=::LoadCursor(0,IDC_ARROW); 
    wc2.hbrBackground=(HBRUSH)::GetStockObject(WHITE_BRUSH); 
    wc2.lpszMenuName=0; 
    wc2.lpszClassName=L"second class"; 
    // Window 3 
    WNDCLASS wc3; 
    wc3.style=CS_HREDRAW|CS_VREDRAW; 
    wc3.lpfnWndProc=WndProc3; 
    wc3.cbClsExtra=0; 
    wc3.cbWndExtra=0; 
    wc3.hInstance=ghAppInst; 
    wc3.hIcon=::LoadIcon(0,IDI_APPLICATION); 
    wc3.hCursor=::LoadCursor(0,IDC_ARROW); 
    wc3.hbrBackground=(HBRUSH)::GetStockObject(WHITE_BRUSH); 
    wc3.lpszMenuName=0; 
    wc3.lpszClassName=L"third class"; 
    // Step 3: Register with WNDCLASS instance with windows. 
    RegisterClass(&wc1); 
    RegisterClass(&wc2); 
    RegisterClass(&wc3); 
    // Step 4: Create the window, and save the handle in global window handle variable ghMainWnd. 
    ghFirstWnd=::CreateWindow(L"MyWndClassName",L"MyWindow1",WS_OVERLAPPEDWINDOW,0,0,50,50,0,0,ghAppInst,0); 
    ghSecondWnd=::CreateWindow(L"MyWndClassName",L"MyWindow2",WS_OVERLAPPEDWINDOW,50,0,50,50,0,0,ghAppInst,0); 
    ghThirdWnd=::CreateWindow(L"MyWndClassName",L"MyWindow3",WS_OVERLAPPEDWINDOW,100,0,50,50,0,0,ghAppInst,0); 
    if(ghFirstWnd==0) 
    { 
     ::MessageBox(0,L"create window1-failed",0,0); 
     return false; 
    } 
    if(ghSecondWnd==0) 
    { 
     ::MessageBox(0,L"create window2 failed",0,0); 
     return false; 
    } 
    if(ghThirdWnd==0) 
    { 
     ::MessageBox(0,L"create window3 failed",0,0); 
     return false; 
    } 
    // Step 5: Show and update the window. 
    ShowWindow(ghFirstWnd,showCmd); 
    UpdateWindow(ghFirstWnd); 
    ShowWindow(ghSecondWnd,showCmd); 
    UpdateWindow(ghSecondWnd); 
    ShowWindow(ghThirdWnd,showCmd); 
    UpdateWindow(ghThirdWnd); 
    // Step 6: Enter the message loop and don't quit until a WM_QUIT message is received. 
    MSG msg; 
    ZeroMemory(&msg,sizeof(MSG)); 
    while(GetMessage(&msg,0,0,0)) 
    { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 
    // Return exit code back to operating system. 
    return(int)msg.wParam; 
} 

проблема в том, что я пытаюсь выполнить код, который он просто сказал, создаст окно1- не удалось!

+1

Выполняйте документацию, и если 'CreateWindow' терпит неудачу, вызовите' GetLastError' сразу после (перед другими вызовами API), чтобы получить дополнительную информацию. – chris

+0

Это также яркий пример того, как сократить минимальный тестовый пример. Окно 1 не создается. Избавьтесь от окон 2 и 3, и вы мгновенно потеряете 2/3 кода, чтобы просмотреть, считая, что он все еще терпит неудачу. – chris

ответ

0

Функция CreateWindow возвращает дескриптор в окна или после сбоя возвращает NULL. Итак, замените «if (ghFirstWnd == 0)» на «if (ghFirstWnd == NULL)» и проверьте, что происходит. Я не уверен, потому что я не использую Win32.

Если только «создать окно1- возможно, попробуйте заменить «if (ghSecondWnd == 0)» на «if (ghSecondWnd == 1)», а затем должны появиться два окна сообщений.

+0

Программа выйдет после отображения сообщения. И хотя 'nullptr' является правильной вещью для использования для нулевых указателей (это не имеет ничего общего с Win32),' if (! GhFirstWnd) 'лучше. В любом случае это ничего не меняет. 'NULL' должен оцениваться в 0, поэтому, если он компилируется, я не вижу, как изменение может изменить семантику. – chris

2

Вырезать программу можно, что-то похожее на это (я сделал пару изменений в самом коде, но это должно работать в C++ 03).

#include <Windows.h> 

int WINAPI 
WinMain(HINSTANCE hInstance, HINSTANCE, PSTR,int showCmd) 
{ 
    WNDCLASS wc1 = {}; 
    wc1.style = CS_HREDRAW|CS_VREDRAW; 
    wc1.lpfnWndProc = DefWindowProc; 
    wc1.hInstance = hInstance; 
    wc1.hIcon = ::LoadIcon(0,IDI_APPLICATION); 
    wc1.hCursor = ::LoadCursor(0,IDC_ARROW); 
    wc1.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH); 
    wc1.lpszClassName = L"first class"; 

    RegisterClass(&wc1); 
    HWND ghFirstWnd = ::CreateWindow(L"MyWndClassName",L"MyWindow1",WS_OVERLAPPEDWINDOW,0,0,50,50,0,0,hInstance,0); 

    if(!ghFirstWnd) 
    { 
     ::MessageBox(0,L"create window1-failed",0,0); 
     return 1; 
    } 

    return 0; 
} 

с помощью этой небольшой код, это гораздо легче обнаружить свою ошибку ваш класс окна имеет имя «первый класс», но в вашем вызове CreateWindow вы используете класс с именем «MyWndClassName». Класс не может быть найден, поэтому с ним нельзя создать окно.

На боковой ноте у вас мало проверочных проверок. Одна вещь, которая действительно сильно повлияла бы на это, - GetLastError.

+0

ОК, который сработал. изменил «MyWndClassName» на «первый класс» «второй класс» и «третий класс», – cniper