继续前面的分析,上次说到需要调用函数co_WinPosShowWindow来显示窗口,那么这个函数里怎么样实现窗口的显示呢?实现代码如下:
#001 BOOLEAN FASTCALL
#002 co_WinPosShowWindow(PWINDOW_OBJECT Window, INT Cmd)
#003 {
#004 BOOLEAN WasVisible;
#005 UINT Swp = 0;
#006 RECT NewPos;
#007 BOOLEAN ShowFlag;
#008 // HRGN VisibleRgn;
#009 PWINDOW Wnd;
#010
#011 ASSERT_REFS_CO(Window);
获取窗口句柄。
#012 Wnd = Window->Wnd;
#013
#014 if (!Wnd) return FALSE;
#015
判断窗口是否可见。
#016 WasVisible = (Wnd->Style & WS_VISIBLE) != 0;
#017
根据窗口显示命令来进行不同代码执行。
#018 switch (Cmd)
#019 {
把窗口隐藏的命令。
#020 case SW_HIDE:
#021 {
#022 if (!WasVisible)
#023 {
#024 return(FALSE);
#025 }
#026 Swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE;
#027 if (Window->hSelf != UserGetActiveWindow())
#028 Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
#029 break;
#030 }
#031
把窗口显示为最小化的命令。
#032 case SW_SHOWMINNOACTIVE:
#033 Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
#034 /* Fall through. */
#035 case SW_SHOWMINIMIZED:
#036 Swp |= SWP_SHOWWINDOW;
#037 /* Fall through. */
#038 case SW_MINIMIZE:
#039 {
#040 Swp |= SWP_NOACTIVATE;
#041 if (!(Wnd->Style & WS_MINIMIZE))
#042 {
#043 Swp |= co_WinPosMinMaximize(Window, SW_MINIMIZE, &NewPos) |
#044 SWP_FRAMECHANGED;
#045 }
#046 else
#047 {
#048 Swp |= SWP_NOSIZE | SWP_NOMOVE;
#049 if (! WasVisible)
#050 {
#051 Swp |= SWP_FRAMECHANGED;
#052 }
#053 }
#054 break;
#055 }
#056
窗口最大化的命令。
#057 case SW_SHOWMAXIMIZED:
#058 {
#059 Swp |= SWP_SHOWWINDOW;
#060 if (!(Wnd->Style & WS_MAXIMIZE))
#061 {
#062 Swp |= co_WinPosMinMaximize(Window, SW_MAXIMIZE, &NewPos) |
#063 SWP_FRAMECHANGED;
#064 }
#065 else
#066 {
#067 Swp |= SWP_NOSIZE | SWP_NOMOVE;
#068 if (! WasVisible)
#069 {
#070 Swp |= SWP_FRAMECHANGED;
#071 }
#072 }
#073 break;
#074 }
#075
一般显示窗口的命令。
#076 case SW_SHOWNA:
#077 Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
#078 /* Fall through. */
#079 case SW_SHOW:
#080 if (WasVisible) return(TRUE); // Nothing to do!
#081 Swp |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
#082 /* Don't activate the topmost window. */
#083 break;
#084
恢复窗口显示的命令。
#085 case SW_SHOWNOACTIVATE:
#086 //Swp |= SWP_NOZORDER;
#087 Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
#088 /* Fall through. */
#089 case SW_SHOWNORMAL:
#090 case SW_SHOWDEFAULT:
#091 case SW_RESTORE:
#092 Swp |= SWP_SHOWWINDOW;
#093 if (Wnd->Style & (WS_MINIMIZE | WS_MAXIMIZE))
#094 {
#095 Swp |= co_WinPosMinMaximize(Window, SW_RESTORE, &NewPos) |
#096 SWP_FRAMECHANGED;
#097 }
#098 else
#099 {
#100 Swp |= SWP_NOSIZE | SWP_NOMOVE;
#101 if (! WasVisible)
#102 {
#103 Swp |= SWP_FRAMECHANGED;
#104 }
#105 }
#106 break;
#107 }
#108
#109 ShowFlag = (Cmd != SW_HIDE);
#110
窗口是否需要隐藏或者显示。
#111 if (ShowFlag != WasVisible)
#112 {
发送消息给窗口显示或隐藏。
#113 co_IntSendMessage(Window->hSelf, WM_SHOWWINDOW, ShowFlag, 0);
#114 }
#115
不能显示或隐藏一个非MDI的子窗口。
#116 /* We can't activate a child window */
#117 if ((Wnd->Style & WS_CHILD) &&
#118 !(Wnd->ExStyle & WS_EX_MDICHILD))
#119 {
#120 Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
#121 }
#122
设置窗口的位置和显示状态。
#123 co_WinPosSetWindowPos(Window, 0 != (Wnd->ExStyle & WS_EX_TOPMOST)
#124 ? HWND_TOPMOST : HWND_TOP,
#125 NewPos.left, NewPos.top, NewPos.right, NewPos.bottom, LOWORD(Swp));
#126
设置窗口隐藏,并设置其它窗口显示出来。
#127 if (Cmd == SW_HIDE)
#128 {
#129 PWINDOW_OBJECT ThreadFocusWindow;
#130
#131 /* FIXME: This will cause the window to be activated irrespective
#132 * of whether it is owned by the same thread. Has to be done
#133 * asynchronously.
#134 */
#135
#136 if (Window->hSelf == UserGetActiveWindow())
#137 {
#138 co_WinPosActivateOtherWindow(Window);
#139 }
#140
#141
#142 //temphack
#143 ThreadFocusWindow = UserGetWindowObject(IntGetThreadFocusWindow());
#144
把焦点转移到父窗口。
#145 /* Revert focus to parent */
#146 if (ThreadFocusWindow && (Window == ThreadFocusWindow ||
#147 IntIsChildWindow(Window, ThreadFocusWindow)))
#148 {
#149 //faxme: as long as we have ref on Window, we also, indirectly, have ref on parent...
#150 co_UserSetFocus(Window->Parent);
#151 }
#152 }
#153
#154 /* FIXME: Check for window destruction. */
#155
发送窗口改变大小、移动的消息。
#156 if ((Window->Flags & WINDOWOBJECT_NEED_SIZE) &&
#157 !(Window->Status & WINDOWSTATUS_DESTROYING))
#158 {
#159 WPARAM wParam = SIZE_RESTORED;
#160
#161 Window->Flags &= ~WINDOWOBJECT_NEED_SIZE;
#162 if (Wnd->Style & WS_MAXIMIZE)
#163 {
#164 wParam = SIZE_MAXIMIZED;
#165 }
#166 else if (Wnd->Style & WS_MINIMIZE)
#167 {
#168 wParam = SIZE_MINIMIZED;
#169 }
#170
#171 co_IntSendMessage(Window->hSelf, WM_SIZE, wParam,
#172 MAKELONG(Wnd->ClientRect.right -
#173 Wnd->ClientRect.left,
#174 Wnd->ClientRect.bottom -
#175 Wnd->ClientRect.top));
#176 co_IntSendMessage(Window->hSelf, WM_MOVE, 0,
#177 MAKELONG(Wnd->ClientRect.left,
#178 Wnd->ClientRect.top));
#179 IntEngWindowChanged(Window, WOC_RGN_CLIENT);
#180
#181 }
#182
#183 /* Activate the window if activation is not requested and the window is not minimized */
#184 /*
改变窗口最小化的动作。
#185 if (!(Swp & (SWP_NOACTIVATE | SWP_HIDEWINDOW)) && !(Window->Style & WS_MINIMIZE))
#186 {
#187 WinPosChangeActiveWindow(Wnd, FALSE);
#188 }
#189 */
#190 return(WasVisible);
#191 }