Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

help.c

Go to the documentation of this file.
00001 /**************************** Module Header ********************************\ 00002 * Module Name: help.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * Help function 00007 * 00008 * History: 00009 * 04-15-91 JimA Ported. 00010 \***************************************************************************/ 00011 00012 #include "precomp.h" 00013 #pragma hdrstop 00014 00015 DWORD _GetWindowContextHelpId(PWND pWnd) 00016 { 00017 return (DWORD)(ULONG_PTR)_GetProp(pWnd, MAKEINTATOM(gpsi->atomContextHelpIdProp), 00018 PROPF_INTERNAL); 00019 } 00020 00021 00022 BOOL _SetWindowContextHelpId(PWND pWnd, DWORD dwContextId) 00023 { 00024 //If dwContextId is NULL, then this implies that the caller wants to 00025 // remove the dwContextId associated with this Window. 00026 if(dwContextId == 0) { 00027 InternalRemoveProp(pWnd, MAKEINTATOM(gpsi->atomContextHelpIdProp), 00028 PROPF_INTERNAL); 00029 return(TRUE); 00030 } 00031 00032 return (InternalSetProp(pWnd, MAKEINTATOM(gpsi->atomContextHelpIdProp), 00033 (HANDLE)LongToHandle( dwContextId ), PROPF_INTERNAL | PROPF_NOPOOL)); 00034 } 00035 00036 00037 /***************************************************************************\ 00038 * SendHelpMessage 00039 * 00040 * 00041 \***************************************************************************/ 00042 00043 void xxxSendHelpMessage( 00044 PWND pwnd, 00045 int iType, 00046 int iCtrlId, 00047 HANDLE hItemHandle, 00048 DWORD dwContextId) 00049 { 00050 HELPINFO HelpInfo; 00051 long lValue; 00052 00053 CheckLock(pwnd); 00054 00055 HelpInfo.cbSize = sizeof(HELPINFO); 00056 HelpInfo.iContextType = iType; 00057 HelpInfo.iCtrlId = iCtrlId; 00058 HelpInfo.hItemHandle = hItemHandle; 00059 HelpInfo.dwContextId = dwContextId; 00060 00061 lValue = _GetMessagePos(); 00062 HelpInfo.MousePos.x = GET_X_LPARAM(lValue); 00063 HelpInfo.MousePos.y = GET_Y_LPARAM(lValue); 00064 00065 xxxSendMessage(pwnd, WM_HELP, 0, (LPARAM)(LPHELPINFO)&HelpInfo); 00066 } 00067 00068 00069 /* 00070 * Modal loop for when the user has selected the help icon from the titlebar 00071 * 00072 */ 00073 VOID xxxHelpLoop(PWND pwnd) 00074 { 00075 HWND hwndChild; 00076 PWND pwndChild; 00077 PWND pwndControl; 00078 MSG msg; 00079 RECT rc; 00080 int cBorders; 00081 PTHREADINFO ptiCurrent = PtiCurrent(); 00082 DLGENUMDATA DlgEnumData; 00083 TL tlpwndChild; 00084 00085 CheckLock(pwnd); 00086 UserAssert(IsWinEventNotifyDeferredOK()); 00087 00088 if (FWINABLE()) { 00089 xxxWindowEvent(EVENT_SYSTEM_CONTEXTHELPSTART, pwnd, OBJID_WINDOW, 00090 INDEXID_CONTAINER, 0); 00091 } 00092 00093 zzzSetCursor(SYSCUR(HELP)); 00094 xxxCapture(ptiCurrent, pwnd, SCREEN_CAPTURE); 00095 00096 cBorders = GetWindowBorders(pwnd->style, pwnd->ExStyle, TRUE, FALSE); 00097 00098 CopyInflateRect(&rc, &pwnd->rcWindow, -cBorders * SYSMET(CXBORDER), -cBorders * SYSMET(CYBORDER)); 00099 00100 while (ptiCurrent->pq->spwndCapture == pwnd) { 00101 if (!xxxPeekMessage(&msg, NULL, 0, 0, PM_NOYIELD | PM_NOREMOVE)) { 00102 xxxWaitMessage(); 00103 continue; 00104 } 00105 00106 if (msg.message == WM_NCLBUTTONDOWN) { 00107 break; 00108 } else if (msg.message == WM_LBUTTONDOWN) { 00109 /* 00110 * If user clicked outside of window client, bail out now. 00111 */ 00112 if (!PtInRect(&rc, msg.pt)) 00113 break; 00114 00115 /* 00116 * WindowHitTest() won't return a static control's handle 00117 */ 00118 hwndChild = xxxWindowHitTest(pwnd, msg.pt, NULL, 0); 00119 pwndChild = ValidateHwnd( hwndChild ); 00120 ThreadLock(pwndChild, &tlpwndChild); 00121 00122 if (pwndChild && FIsParentDude(pwndChild)) 00123 { 00124 /* 00125 * If this is a dialog class, then one of three things has 00126 * happened: 00127 * 00128 * o This is a static text control 00129 * o This is the background of the dialog box. 00130 * 00131 * What we do is enumerate the child windows and see if 00132 * any of them contain the current cursor point. If they do, 00133 * change our window handle and continue on. Otherwise, 00134 * return doing nothing -- we don't want context-sensitive 00135 * help for a dialog background. 00136 * 00137 * If this is a group box, then we might have clicked on a 00138 * disabled control, so we enumerate child windows to see 00139 * if we get another control. 00140 */ 00141 00142 /* 00143 * We're enumerating a dialog's children. So, if we don't 00144 * find any matches, hwndChild will be NULL and the check 00145 * below will drop out. 00146 */ 00147 DlgEnumData.pwndDialog = pwndChild; 00148 DlgEnumData.pwndControl = NULL; 00149 DlgEnumData.ptCurHelp = msg.pt; 00150 xxxInternalEnumWindow(pwndChild, EnumPwndDlgChildProc, (LPARAM)&DlgEnumData, BWL_ENUMCHILDREN); 00151 pwndControl = DlgEnumData.pwndControl; 00152 } else { 00153 pwndControl = pwndChild; 00154 } 00155 00156 /* 00157 * If we click on nothing, just exit. 00158 */ 00159 if (pwndControl == pwnd) { 00160 pwndControl = NULL; 00161 } 00162 00163 /* 00164 * HACK ALERT (Visual Basic 4.0) - they have their own non-window 00165 * based controls that draw directly on the main dialog. In order 00166 * to provide help for these controls, we pass along the WM_HELP 00167 * message iff the main dialog has a context id assigned. 00168 * 00169 * If the top level window has its own context help ID, 00170 * then pass it in the context help message. 00171 */ 00172 if (!pwndControl) { 00173 if (_GetProp(pwnd, MAKEINTATOM(gpsi->atomContextHelpIdProp), TRUE)) 00174 pwndControl = pwnd; 00175 } 00176 00177 if (pwndControl) { 00178 PWND pwndSend; 00179 int id; 00180 TL tlpwndSend; 00181 TL tlpwndControl; 00182 00183 ThreadLockAlways(pwndControl, &tlpwndControl); 00184 00185 zzzSetCursor(SYSCUR(ARROW)); 00186 xxxReleaseCapture(); 00187 xxxRedrawTitle(pwnd, DC_BUTTONS); 00188 ClrWF(pwnd, WFHELPBUTTONDOWN); 00189 xxxGetMessage(&msg, NULL, 0, 0); 00190 00191 if (FWINABLE()) { 00192 xxxWindowEvent(EVENT_OBJECT_STATECHANGE, pwnd, OBJID_TITLEBAR, 00193 INDEX_TITLEBAR_HELPBUTTON, FALSE); 00194 00195 xxxWindowEvent(EVENT_SYSTEM_CONTEXTHELPEND, pwnd, OBJID_WINDOW, 00196 INDEXID_CONTAINER, FALSE); 00197 } 00198 00199 /* 00200 * Determine the ID of the control 00201 * We used to always sign extend, but Win98 doesn't do that 00202 * so we only sign extend 0xffff. MCostea #218711 00203 */ 00204 if (TestwndChild(pwndControl)) { 00205 id = PTR_TO_ID(pwndControl->spmenu); 00206 if (id == 0xffff) { 00207 id = -1; 00208 } 00209 } else { 00210 id = -1; 00211 } 00212 00213 /* 00214 * Disabled controls and static controls won't pass this 00215 * on to their parent, so instead, we send the message to 00216 * their parent. 00217 */ 00218 00219 if (TestWF(pwndControl, WFDISABLED)) { 00220 PWND pwndParent = _GetParent(pwndControl); 00221 if (!pwndParent) 00222 { 00223 ThreadUnlock( &tlpwndControl ); 00224 ThreadUnlock( &tlpwndChild ); 00225 return; 00226 } 00227 pwndSend = pwndParent; 00228 } else { 00229 pwndSend = pwndControl; 00230 } 00231 00232 ThreadLockAlways(pwndSend, &tlpwndSend); 00233 xxxSendHelpMessage( pwndSend, HELPINFO_WINDOW, id, 00234 (HANDLE)HWq(pwndControl), GetContextHelpId(pwndControl)); 00235 ThreadUnlock(&tlpwndSend); 00236 ThreadUnlock(&tlpwndControl); 00237 ThreadUnlock(&tlpwndChild); 00238 return; 00239 } 00240 ThreadUnlock(&tlpwndChild); 00241 break; 00242 00243 } 00244 else if ((msg.message == WM_RBUTTONDOWN) || 00245 (msg.message == WM_MBUTTONDOWN) || 00246 (msg.message == WM_XBUTTONDOWN)) { 00247 /* 00248 * fix bug 29852; break the loop for right and middle buttons 00249 * and pass along the messages to the control 00250 */ 00251 break; 00252 } 00253 else if (msg.message == WM_MOUSEMOVE) { 00254 if (PtInRect(&rc, msg.pt)) 00255 zzzSetCursor(SYSCUR(HELP)); 00256 else 00257 zzzSetCursor(SYSCUR(ARROW)); 00258 } 00259 else if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE) 00260 { 00261 xxxGetMessage( &msg, NULL, 0, 0 ); 00262 break; 00263 } 00264 00265 xxxGetMessage(&msg, NULL, 0, 0); 00266 xxxTranslateMessage(&msg, 0); 00267 xxxDispatchMessage(&msg); 00268 } 00269 00270 xxxReleaseCapture(); 00271 zzzSetCursor(SYSCUR(ARROW)); 00272 xxxRedrawTitle(pwnd, DC_BUTTONS); 00273 00274 ClrWF(pwnd, WFHELPBUTTONDOWN); 00275 if (FWINABLE()) { 00276 xxxWindowEvent(EVENT_OBJECT_STATECHANGE, pwnd, OBJID_TITLEBAR, 00277 INDEX_TITLEBAR_HELPBUTTON, 0); 00278 00279 xxxWindowEvent(EVENT_SYSTEM_CONTEXTHELPEND, pwnd, OBJID_WINDOW, 00280 INDEXID_CONTAINER, 0); 00281 } 00282 }

Generated on Sat May 15 19:40:17 2004 for test by doxygen 1.3.7