minigui EnableWindow函数分析

src/gui/widown.c line 3607-3628

  1. BOOL GUIAPI EnableWindow (HWND hWnd, BOOL fEnable)
  2. {
  3.     BOOL fOldStatus;
  4.     
  5.     MG_CHECK_RET (MG_IS_NORMAL_WINDOW(hWnd), FALSE);
  6.     if (IsMainWindow (hWnd)) {
  7.         fOldStatus = SendMessage (HWND_DESKTOP, MSG_ENABLEMAINWIN,
  8.                         (WPARAM)hWnd, (LPARAM)fEnable);
  9.     }
  10.     else {
  11.         PCONTROL pControl;
  12.         pControl = (PCONTROL)hWnd;
  13.         
  14.         fOldStatus = !(pControl->dwStyle & WS_DISABLED);
  15.     }
  16.     
  17.     SendNotifyMessage (hWnd, MSG_ENABLE, fEnable, 0);
  18.     return fOldStatus;
  19. }

 

这里的两个参数hWnd指定要操作的窗口句柄, fEnable指定enable 或者disable hWnd指定的窗口。然后判断下指定的窗口是否为主窗口。如果是,则向桌面线程发送消息MSG_ENABLEMAINWIN,并附带hWndfEnable信息。这个消息的处理代码在src/kernel/desktop-comm.c中定义

 

src/kernel/desktop-comm.c line 2146-2169

  1.         case MSG_ENABLEMAINWIN:
  2.             iRet = !(pWin->dwStyle & WS_DISABLED);
  3.             if ( (!(pWin->dwStyle & WS_DISABLED) && !lParam)
  4.                     || ((pWin->dwStyle & WS_DISABLED) && lParam) ) {
  5.                 if (lParam)
  6.                     pWin->dwStyle &= ~WS_DISABLED;
  7.                 else
  8.                     pWin->dwStyle |=  WS_DISABLED;
  9.                 if (pWin->dwStyle & WS_DISABLED) {
  10.                 
  11.                     if (__mg_capture_wnd && GetMainWindowPtrOfControl (__mg_capture_wnd) == pWin) 
  12.                         __mg_capture_wnd = 0;
  13.                     if (__mg_active_mainwnd == pWin) {
  14.                         dskChangActiveWindow (NULL);
  15.                         break;
  16.                     }
  17.                 }
  18.                 SendAsyncMessage ((HWND)pWin, MSG_NCPAINT, 0, 0);
  19.             }
  20.             break;

 

 

从这段代码可以看出,如果是disable窗口,首先此窗口中捕获鼠标的控件会释放鼠标。如果这个被disable的窗口是当前活动窗口,则调用函数dskChangActiveWindow改变当前活动窗口

 

src/kernel/desktop-comm.c line  507-534

  1. static PMAINWIN dskChangActiveWindow (PMAINWIN pWin)
  2. {
  3.     PMAINWIN pOldActive;
  4.     if (__mg_ime_wnd && (__mg_ime_wnd == (HWND)pWin))
  5.         return __mg_active_mainwnd;
  6.     if ((pWin == __mg_active_mainwnd) 
  7.                     || (pWin && (pWin->dwExStyle & WS_EX_TOOLWINDOW)))
  8.         return __mg_active_mainwnd;
  9.     pOldActive = __mg_active_mainwnd;
  10.     DesktopSetActiveWindow (pWin);
  11.     if (pOldActive && (pOldActive->dwStyle & WS_VISIBLE)) {
  12.         SendAsyncMessage ((HWND)pOldActive, MSG_NCACTIVATE, FALSE, 0);
  13.         SendNotifyMessage ((HWND)pOldActive, MSG_ACTIVE, FALSE, 0);
  14.         SendNotifyMessage ((HWND)pOldActive, MSG_KILLFOCUS, (HWND)pWin, 0);
  15.     }
  16.     if (pWin) {
  17.         SendAsyncMessage ((HWND)pWin, MSG_NCACTIVATE, TRUE, 0);
  18.         SendNotifyMessage ((HWND)pWin, MSG_ACTIVE, TRUE, 0);
  19.         SendNotifyMessage ((HWND)pWin, MSG_SETFOCUS, (HWND)pOldActive, 0);
  20.     }
  21.     return pOldActive;
  22. }

 

在调用此函数时,给他传递的参数为NULL,所以在此函数中调用DesktopSetActiveWindow (pWin)设置当前活动窗口时,当前活动窗口将被设置为NULL,即没有活动窗口,此时按键不会有任何窗口进行响应。

 

再回头看桌面线程对MSG_ENABLEMAINWIN消息的处理,

 

src/kernel/desktop-comm.c line 2146-2169

  1.         case MSG_ENABLEMAINWIN:
  2.             iRet = !(pWin->dwStyle & WS_DISABLED);
  3.             if ( (!(pWin->dwStyle & WS_DISABLED) && !lParam)
  4.                     || ((pWin->dwStyle & WS_DISABLED) && lParam) ) {
  5.                 if (lParam)
  6.                     pWin->dwStyle &= ~WS_DISABLED;
  7.                 else
  8.                     pWin->dwStyle |=  WS_DISABLED;
  9.                 if (pWin->dwStyle & WS_DISABLED) {
  10.                 
  11.                     if (__mg_capture_wnd && GetMainWindowPtrOfControl (__mg_capture_wnd) == pWin) 
  12.                         __mg_capture_wnd = 0;
  13.                     if (__mg_active_mainwnd == pWin) {
  14.                         dskChangActiveWindow (NULL);
  15.                         break;
  16.                     }
  17.                 }
  18.                 SendAsyncMessage ((HWND)pWin, MSG_NCPAINT, 0, 0);
  19.             }
  20.             break;

 

如果是enable窗口的话,则向此窗口发送MSG_NCPAINT消息。这个消息会由DefaultMainWinProc(hWnd,message,wParam,lParam)函数处理,最终会在函数DefaultPaintMsgHandler(PMAINWIN pWin, int message, WPARAM wParam, LPARAM lParam)中对此消息处理。

 

src/gui/window.c  line 2257-2259

  1.         case MSG_NCPAINT:
  2.             wndDrawNCFrame (pWin, (HDC)wParam, (const RECT*)lParam);
  3.         break;

处理时调用wndDrawNCFrame (pWin, (HDC)wParam, (const RECT*)lParam);将窗口的非窗户区边框进行重绘。

 

注意,在这里并没有设置活动窗口,如果窗口原来是活动的,在被disable后,再enable,他将不再是活动窗口,也就不会接收任何按键消息。需用函数SetActiveWindow将窗口设置为活动的。

 

你可能感兴趣的:(minigui)