2011-02-15 67 views
4

我在關閉子窗口時出現了問題,主窗口也退出。C++中的子窗口問題

我是這個編程的新手。

正確的代碼:

/** 
    @file MainWindow.cpp 
    @author Andro Bondoc 
    @date 2011-02-11 
*/ 

    /** @file MainWindow.cpp @author Andro Bondoc @date 2011-02-11 */ 

#include "tray.h" 



#define WM_USER_SHELLICON WM_USER + 1 

HWND hWnd, Button, LoadNew, TextBox; 
HINSTANCE hInst; 
HICON hMainIcon; 
HMENU hPopMenu; 
NOTIFYICONDATA structNID; 

long PASCAL WndProcParent(HWND,UINT,UINT,LONG); 
long PASCAL WndProcChild(HWND,UINT,UINT,LONG); 


int APIENTRY WinMain(HINSTANCE hInstance, 
        HINSTANCE hPrevInstance, 
        LPSTR  lpCmdLine, 
        int  nCmdShow) 
{ 

    MSG msg; 
    WNDCLASS wc, ws; 

    hInst = hInstance; 
    if(!hPrevInstance) 
    { 
     wc.style = CS_HREDRAW | CS_VREDRAW; 
     wc.lpfnWndProc = WndProcParent; 
     wc.cbClsExtra = 0; 
     wc.cbWndExtra = 0; 
     wc.hInstance = hInstance; 
     wc.hIcon = LoadIcon(hInstance,(LPCTSTR)MAKEINTRESOURCE(IDI_TRAYICON));//LoadIcon(NULL,IDI_APPLICATION); 
     wc.hCursor = LoadCursor(NULL,IDC_ARROW); 
     wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND; 
     wc.lpszMenuName = NULL; 
     wc.lpszClassName = "Data Retriever Parent"; 
     RegisterClass(&wc); 

     ws.style = CS_HREDRAW | CS_VREDRAW; 
     ws.lpfnWndProc = WndProcChild; 
     ws.cbClsExtra = 0; 
     ws.cbWndExtra = 0; 
     ws.hInstance = hInstance; 
     ws.hIcon = LoadIcon(hInstance,(LPCTSTR)MAKEINTRESOURCE(IDI_TRAYICON));//LoadIcon(NULL,IDI_APPLICATION); 
     ws.hCursor = LoadCursor(NULL,IDC_ARROW); 
     ws.hbrBackground = (HBRUSH)COLOR_BACKGROUND; 
     ws.lpszMenuName = NULL; 
     ws.lpszClassName = "Data Retriever Child"; 
     RegisterClass(&ws); 
    } 

      hWnd = CreateWindowEx(0, wc.lpszClassName, "Data Retriever", 
         WS_BORDER | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, 
         CW_USEDEFAULT, 
         CW_USEDEFAULT, 
         CW_USEDEFAULT, 
         CW_USEDEFAULT, 
         NULL, NULL, hInstance, NULL); 

      LoadNew = CreateWindowEx(0, ws.lpszClassName, "Help Program", 
         WS_BORDER | WS_CAPTION | WS_CHILD, 
         120, 
         80, 
         500, 
         300, 
         hWnd, NULL, hInstance, NULL); 




    hMainIcon = LoadIcon(hInstance,(LPCTSTR)MAKEINTRESOURCE(IDI_TRAYICON)); 


    structNID.cbSize = sizeof(NOTIFYICONDATA); 
    structNID.hWnd = (HWND) hWnd; 
    structNID.uID = IDI_TRAYICON; 
    structNID.uFlags = NIF_ICON | NIF_MESSAGE; 
    structNID.hIcon = hMainIcon; 
    structNID.uCallbackMessage = WM_USER_SHELLICON; 


    Shell_NotifyIcon(NIM_ADD, &structNID); 

    while(GetMessage(&msg,NULL,0,0)) 
    { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 
    return msg.wParam; 
} 



long FAR PASCAL WndProcParent(HWND hwnd,UINT message,UINT wParam,long lParam) 
{ 
    HDC hdc = NULL; 
    POINT lpClickPoint; 
    char buff[100] = ""; 

     switch(message){ 
       case WM_CREATE: 

       Button = CreateWindowEx(WS_EX_WINDOWEDGE, "BUTTON", "Close", 
       WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 680,480, 80, 30, hwnd, (HMENU)ID_CLOSE, 
       GetModuleHandle(NULL), NULL); 

       Button = CreateWindowEx(WS_EX_WINDOWEDGE, "BUTTON", "Help", 
       WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 680,450, 80, 30, hwnd, (HMENU)ID_HELPDAW, 
       GetModuleHandle(NULL), NULL); 

       break; 


     /*case WM_DESTROY: 

       PostQuitMessage(0); 
       return 0;*/ 

     case WM_USER_SHELLICON: 

      switch(LOWORD(lParam)) 
      { 
       case WM_LBUTTONDBLCLK: 
        ShowWindow(hwnd, SW_RESTORE); 
        break; 

       case WM_RBUTTONDOWN: 
        //get mouse cursor position x and y as lParam has the message itself 
        GetCursorPos(&lpClickPoint); 

        //place the window/menu there if needed 

        hPopMenu = CreatePopupMenu(); 
        InsertMenu(hPopMenu,0xFFFFFFFF,MF_BYPOSITION|MF_STRING,ID_OPEN,"&Open"); 
        InsertMenu(hPopMenu,0xFFFFFFFF,MF_BYPOSITION|MF_STRING,ID_HELPDAW,"&Help"); 
        InsertMenu(hPopMenu,0xFFFFFFFF,MF_BYPOSITION|MF_STRING,ID_CLOSE,"&Exit"); 

         //workaround for microsoft bug, to hide menu w/o selecting 
        SetForegroundWindow(hWnd); 
        TrackPopupMenu(hPopMenu,TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_BOTTOMALIGN,lpClickPoint.x, lpClickPoint.y,0,hWnd,NULL); 
        SendMessage(hWnd,WM_NULL,0,0); 

        //MessageBox(NULL,"TEST rightclick","Testing ...",MB_OK); 

        return TRUE; 
      } 

      break; 

     case WM_COMMAND: 

      if(ID_CLOSE == LOWORD(wParam)) 
      { 
       int iRes = MessageBox(NULL,"Do you want to Exit","Data Retriever",MB_YESNO|MB_ICONQUESTION); 
       if(IDYES == iRes) 
       { 
       Shell_NotifyIcon(NIM_DELETE,&structNID); 
       DestroyWindow(hWnd); 
       PostQuitMessage(0); 
       } 

      } 
      else if(ID_HELPDAW == LOWORD(wParam)) 
      { 
       ShowWindow(LoadNew, SW_SHOW); 
       //MessageBox(NULL, "Help","Data Retriever",MB_OK|MB_ICONQUESTION);      
      } 

      else if(ID_OPEN == LOWORD(wParam)) 
      { 
       ShowWindow(hWnd, SW_NORMAL); 
      } 
      break; 

     case WM_CLOSE: 

       Shell_NotifyIcon(NIM_DELETE,&structNID); 
       DestroyWindow(hWnd); 
       PostQuitMessage(0); 

      break; 

     case WM_SYSCOMMAND: 

      if(SC_MINIMIZE == wParam) 
      { 
       ShowWindow(hWnd,SW_HIDE); 
       return TRUE; 
      } 
      break; 

    } 
return DefWindowProc(hwnd,message,wParam,lParam); 
} 

long FAR PASCAL WndProcChild(HWND hwnd,UINT message,UINT wParam,long lParam){ 
    HDC hdc = NULL; 
    PAINTSTRUCT ps; 
    char buff[100] = ""; 
    switch(message){ 
       case WM_CREATE: 

       Button = CreateWindowEx(WS_EX_WINDOWEDGE, "BUTTON", "Unload", 
       WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 20,20, 80, 30, hwnd, (HMENU)ID_MESSAGE, 
       GetModuleHandle(NULL), NULL); 


       break; 


     case WM_COMMAND: 


      if(ID_RETURN == LOWORD(wParam)) 
      { 
       ShowWindow(hWnd, SW_SHOW); 
       ShowWindow(LoadNew,SW_HIDE); 
       //MessageBox(NULL, "Help","Data Retriever",MB_OK|MB_ICONQUESTION);      
      } 


     case WM_CLOSE: 

      ShowWindow(hWnd, SW_SHOW); 
      ShowWindow(LoadNew,SW_HIDE); 
      break; 

     case WM_PAINT: 

      RECT rect; 

      GetClientRect(LoadNew,&rect); 
      hdc = BeginPaint(LoadNew,&ps); 

      strcpy_s(buff,"TOP"); 
      DrawText(hdc,buff,strlen(buff), &rect,DT_SINGLELINE|DT_CENTER|DT_TOP); 
      strcpy_s(buff,"RIGHT"); 
      DrawText(hdc,buff,strlen(buff), &rect,DT_SINGLELINE|DT_VCENTER|DT_RIGHT); 
      strcpy_s(buff,"BOTTOM"); 
      DrawText(hdc,buff,strlen(buff), &rect,DT_SINGLELINE|DT_CENTER|DT_BOTTOM); 
      strcpy_s(buff,"LEFT"); 
      DrawText(hdc,buff,strlen(buff), &rect,DT_SINGLELINE|DT_VCENTER|DT_LEFT); 
      strcpy_s(buff,"CENTER"); 
      DrawText(hdc,buff,strlen(buff), &rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER); 
      strcpy_s(buff,"BOTTOM-LEFT"); 
      DrawText(hdc,buff,strlen(buff), &rect,DT_SINGLELINE|DT_BOTTOM|DT_LEFT); 
      strcpy_s(buff,"BOTTOM-RIGHT"); 
      DrawText(hdc,buff,strlen(buff), &rect,DT_SINGLELINE|DT_BOTTOM|DT_RIGHT); 
      strcpy_s(buff,"TOP-LEFT"); 
      DrawText(hdc,buff,strlen(buff), &rect,DT_SINGLELINE|DT_TOP|DT_LEFT); 
      strcpy_s(buff,"TOP-RIGHT"); 
      DrawText(hdc,buff,strlen(buff), &rect,DT_SINGLELINE|DT_TOP|DT_RIGHT); 

      EndPaint(LoadNew,&ps); 
      break; 
     } 
return DefWindowProc(hwnd,message,wParam,lParam); 
} 
+0

您必須提供更多詳細信息。源代碼會很有幫助。 – Maxpm 2011-02-15 05:26:47

+0

另外,你使用的是哪個操作系統和框架? – 2011-02-15 05:28:30

+0

我假設你正在編寫一個針對Win32 API的程序?請發佈您的代碼的相關部分。對於初學者來說,你可以創建*和*關閉子窗口。 – 2011-02-15 05:30:10

回答

2

您的修改後的代碼仍然對兩個窗口使用相同的WndProc。您嘗試使用相同的類名稱調用RegisterClass兩次。在更改名稱之前,WndProcs不會分開。

ws.lpszClassName = "Data Retriever CHILD"; 

這個問題會更容易理解,如果你選中了來自的RegisterClass返回值 - 目前,第二個呼叫失敗。這個代碼還有其他問題(例如,子WndProc中的MessageBox調用真的很令人討厭),但是這種改變應該足以讓你朝着正確的方向前進。

5

你必須爲每個窗口相同的WndProc代碼。對於WM_CLOSE,您使用DestroyWindow(hWnd),其中hWnd是存儲主窗口的全局變量。

因此,關閉你的子窗口會關閉主窗口,因爲你告訴它。