reactos操作系统实现(177)

前端之家收集整理的这篇文章主要介绍了reactos操作系统实现(177)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

MessageBoxTimeoutIndirectW的实现代码如下:

#001 static int

#002 MessageBoxTimeoutIndirectW(

#003 CONST MSGBoxPARAMSW *lpMsgBoxParams,UINT Timeout)

#004 {

#005 DLGTEMPLATE *tpl;

#006 DLGITEMTEMPLATE *iico,*itxt;

#007 NONCLIENTMETRICSW nclm;

#008 WCHAR capbuf[32];

#009 LPVOID buf;

#010 BYTE *dest;

#011 LPCWSTR caption,text;

#012 HFONT hFont;

#013 HICON Icon;

#014 HDC hDC;

#015 int bufsize,ret,caplen,textlen,btnlen,i,btnleft,btntop,lmargin,nButtons = 0;

#016 LONG Buttons[MSGBoxEX_MAXBTNS];

#017 WCHAR ButtonText[MSGBoxEX_MAXBTNS][MSGBoxEX_MAXBTNSTR];

#018 DLGITEMTEMPLATE *ibtn[MSGBoxEX_MAXBTNS];

#019 RECT btnrect,txtrect,rc;

#020 SIZE btnsize;

#021 MSGBoxINFO mbi;

#022 BOOL defbtn = FALSE;

获取对话框架基本显示单元的大小。

#023 DWORD units = GetDialogBaseUnits();

#024

判断是否设置有显示标题字符串,如果没有设置,就从用户应用程序里获取错误显示字符串作为标题

#025 if(!lpMsgBoxParams->lpszCaption || !HIWORD((LPWSTR)lpMsgBoxParams->lpszCaption))

#026 {

#027 LoadStringW(User32Instance,IDS_ERROR,&capbuf[0],32);

#028 caption = &capbuf[0];

#029 }

#030 else

#031 caption = (LPWSTR)lpMsgBoxParams->lpszCaption;

#032

判断是否需要显示的字符串。

#033 if(!lpMsgBoxParams->lpszText || !HIWORD(lpMsgBoxParams->lpszText))

#034 text = L"";

#035 else

#036 text = lpMsgBoxParams->lpszText;

#037

获取标题显示字符串的大小。

#038 caplen = strlenW(caption);

#039 textlen = strlenW(text);

#040

根据用户的设置来选择显示什么类型的按钮。

#041 /* Create selected buttons */

#042 switch(lpMsgBoxParams->dwStyle & MB_TYPEMASK)

#043 {

#044 case MB_OKCANCEL:

#045 Buttons[0] = IDOK;

#046 Buttons[1] = IDCANCEL;

#047 nButtons = 2;

#048 break;

#049 case MB_CANCELTRYCONTINUE:

#050 Buttons[0] = IDCANCEL;

#051 Buttons[1] = IDTRYAGAIN;

#052 Buttons[2] = IDCONTINUE;

#053 nButtons = 3;

#054 break;

#055 case MB_ABORTRETRYIGNORE:

#056 Buttons[0] = IDABORT;

#057 Buttons[1] = IDRETRY;

#058 Buttons[2] = IDIGNORE;

#059 nButtons = 3;

#060 break;

#061 case MB_YESNO:

#062 Buttons[0] = IDYES;

#063 Buttons[1] = IDNO;

#064 nButtons = 2;

#065 break;

#066 case MB_YESNOCANCEL:

#067 Buttons[0] = IDYES;

#068 Buttons[1] = IDNO;

#069 Buttons[2] = IDCANCEL;

#070 nButtons = 3;

#071 break;

#072 case MB_RETRYCANCEL:

#073 Buttons[0] = IDRETRY;

#074 Buttons[1] = IDCANCEL;

#075 nButtons = 2;

#076 break;

#077 case MB_OK:

#078 /* fall through */

#079 default:

#080 Buttons[0] = IDOK;

#081 nButtons = 1;

#082 break;

#083 }

判断是否显示帮助按钮。

#084 /* Create Help button */

#085 if(lpMsgBoxParams->dwStyle & MB_HELP)

#086 Buttons[nButtons++] = IDHELP;

#087

根据用户设置选择什么类型的图标显示,并调用函数MessageBeep提示不同的提示声音。

#088 switch(lpMsgBoxParams->dwStyle & MB_ICONMASK)

#089 {

#090 case MB_ICONEXCLAMATION:

#091 Icon = LoadIconW(0,IDI_EXCLAMATIONW);

#092 MessageBeep(MB_ICONEXCLAMATION);

#093 break;

#094 case MB_ICONQUESTION:

#095 Icon = LoadIconW(0,IDI_QUESTIONW);

#096 MessageBeep(MB_ICONQUESTION);

#097 break;

#098 case MB_ICONASTERISK:

#099 Icon = LoadIconW(0,IDI_ASTERISKW);

#100 MessageBeep(MB_ICONASTERISK);

#101 break;

#102 case MB_ICONHAND:

#103 Icon = LoadIconW(0,IDI_HANDW);

#104 MessageBeep(MB_ICONHAND);

#105 break;

#106 case MB_USERICON:

#107 Icon = LoadIconW(lpMsgBoxParams->hInstance,lpMsgBoxParams->lpszIcon);

#108 MessageBeep(MB_OK);

#109 break;

#110 default:

#111 /* By default,Windows 95/98/NT does not associate an icon to message Boxes.

#112 * So ReactOS should do the same.

#113 */

#114 Icon = (HICON)0;

#115 MessageBeep(MB_OK);

#116 break;

#117 }

#118

分配基本空间的大小。

#119 /* Basic space */

#120 bufsize = sizeof(DLGTEMPLATE) +

#121 2 * sizeof(WORD) + /* menu and class */

#122 (caplen + 1) * sizeof(WCHAR); /* title */

#123

图标占用空间的大小。

#124 /* Space for icon */

#125 if (NULL != Icon)

#126 {

#127 bufsize = (bufsize + 3) & ~3;

#128 bufsize += sizeof(DLGITEMTEMPLATE) +

#129 4 * sizeof(WORD) +

#130 sizeof(WCHAR);

#131 }

#132

显示字符串占用空间。

#133 /* Space for text */

#134 bufsize = (bufsize + 3) & ~3;

#135 bufsize += sizeof(DLGITEMTEMPLATE) +

#136 3 * sizeof(WORD) +

#137 (textlen + 1) * sizeof(WCHAR);

#138

#139

加载所有按钮的字符串。

#140 for(i = 0; i < nButtons; i++)

#141 {

#142 switch(Buttons[i])

#143 {

#144 case IDOK:

#145 LoadStringW(User32Instance,IDS_OK,ButtonText[i],MSGBoxEX_MAXBTNSTR - 1);

#146 break;

#147 case IDCANCEL:

#148 LoadStringW(User32Instance,IDS_CANCEL,MSGBoxEX_MAXBTNSTR - 1);

#149 break;

#150 case IDYES:

#151 LoadStringW(User32Instance,IDS_YES,MSGBoxEX_MAXBTNSTR - 1);

#152 break;

#153 case IDNO:

#154 LoadStringW(User32Instance,IDS_NO,MSGBoxEX_MAXBTNSTR - 1);

#155 break;

#156 case IDTRYAGAIN:

#157 LoadStringW(User32Instance,IDS_TRYAGAIN,MSGBoxEX_MAXBTNSTR - 1);

#158 break;

#159 case IDCONTINUE:

#160 LoadStringW(User32Instance,IDS_CONTINUE,MSGBoxEX_MAXBTNSTR - 1);

#161 break;

#162 case IDABORT:

#163 LoadStringW(User32Instance,IDS_ABORT,MSGBoxEX_MAXBTNSTR - 1);

#164 break;

#165 case IDRETRY:

#166 LoadStringW(User32Instance,IDS_RETRY,MSGBoxEX_MAXBTNSTR - 1);

#167 break;

#168 case IDIGNORE:

#169 LoadStringW(User32Instance,IDS_IGNORE,MSGBoxEX_MAXBTNSTR - 1);

#170 break;

#171 case IDHELP:

#172 LoadStringW(User32Instance,IDS_HELP,MSGBoxEX_MAXBTNSTR - 1);

#173 break;

#174 default:

#175 ButtonText[i][0] = (WCHAR)0;

#176 break;

#177 }

#178

按钮的空间大小。

#179 /* Space for buttons */

#180 bufsize = (bufsize + 3) & ~3;

#181 bufsize += sizeof(DLGITEMTEMPLATE) +

#182 3 * sizeof(WORD) +

#183 (wcslen(ButtonText[i]) + 1) * sizeof(WCHAR);

#184 }

#185

从进程堆空间里分配内存。

#186 buf = RtlAllocateHeap(GetProcessHeap(),bufsize);

#187 if(!buf)

#188 {

#189 return 0;

#190 }

#191 iico = itxt = NULL;

#192

创建一个兼容DC

#193 hDC = CreateCompatibleDC(0);

#194

下面获取消息窗口显示的字体。

#195 nclm.cbSize = sizeof(nclm);

#196 SystemParametersInfoW (SPI_GETNONCLIENTMETRICS,sizeof(nclm),&nclm,0);

#197 hFont = CreateFontIndirectW (&nclm.lfMessageFont);

#198

下面开始根据对话框的资源结构在内存里构造窗口显示模板。

#199 tpl = (DLGTEMPLATE *)buf;

#200

#201 tpl->style = WS_CAPTION | WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_SYSMENU | DS_CENTER | DS_MODALFRAME | DS_NOIDLEMSG;

#202 tpl->dwExtendedStyle = WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT;

#203 if(lpMsgBoxParams->dwStyle & MB_TOPMOST)

#204 tpl->dwExtendedStyle |= WS_EX_TOPMOST;

#205 if(lpMsgBoxParams->dwStyle & MB_RIGHT)

#206 tpl->dwExtendedStyle |= WS_EX_RIGHT;

#207 tpl->x = 100;

#208 tpl->y = 100;

#209 tpl->cdit = nButtons + ((Icon != (HICON)0) ? 1 : 0) + 1;

#210

#211 dest = (BYTE *)(tpl + 1);

#212

#213 *(WORD*)dest = 0; /* no menu */

#214 *(((WORD*)dest) + 1) = 0; /* use default window class */

#215 dest += 2 * sizeof(WORD);

#216 memcpy(dest,caption,caplen * sizeof(WCHAR));

#217 dest += caplen * sizeof(WCHAR);

#218 *(WCHAR*)dest = L'/0';

#219 dest += sizeof(WCHAR);

#220

创建图标。

#221 /* Create icon */

#222 if(Icon)

#223 {

#224 dest = (BYTE*)(((ULONG_PTR)dest + 3) & ~3);

#225 iico = (DLGITEMTEMPLATE *)dest;

#226 iico->style = WS_CHILD | WS_VISIBLE | SS_ICON;

#227 iico->dwExtendedStyle = 0;

#228 iico->id = MSGBox_IDICON;

#229

#230 dest += sizeof(DLGITEMTEMPLATE);

#231 *(WORD*)dest = 0xFFFF;

#232 dest += sizeof(WORD);

#233 *(WORD*)dest = 0x0082; /* static control */

#234 dest += sizeof(WORD);

#235 *(WORD*)dest = 0xFFFF;

#236 dest += sizeof(WORD);

#237 *(WCHAR*)dest = 0;

#238 dest += sizeof(WCHAR);

#239 *(WORD*)dest = 0;

#240 dest += sizeof(WORD);

#241 }

#242

创建静态框显示字符串。

#243 /* create static for text */

#244 dest = (BYTE*)(((DWORD)dest + 3) & ~3);

#245 itxt = (DLGITEMTEMPLATE *)dest;

#246 itxt->style = WS_CHILD | WS_VISIBLE | SS_NOPREFIX;

#247 if(lpMsgBoxParams->dwStyle & MB_RIGHT)

#248 itxt->style |= SS_RIGHT;

#249 else

#250 itxt->style |= SS_LEFT;

#251 itxt->dwExtendedStyle = 0;

#252 itxt->id = MSGBox_IDTEXT;

#253 dest += sizeof(DLGITEMTEMPLATE);

#254 *(WORD*)dest = 0xFFFF;

#255 dest += sizeof(WORD);

#256 *(WORD*)dest = 0x0082; /* static control */

#257 dest += sizeof(WORD);

#258 memcpy(dest,text,textlen * sizeof(WCHAR));

#259 dest += textlen * sizeof(WCHAR);

#260 *(WCHAR*)dest = 0;

#261 dest += sizeof(WCHAR);

#262 *(WORD*)dest = 0;

#263 dest += sizeof(WORD);

#264

创建要显示的按钮。

#265 /* create buttons */

#266 btnsize.cx = BTN_CX;

#267 btnsize.cy = BTN_CY;

#268 btnrect.left = btnrect.top = 0;

#269 for(i = 0; i < nButtons; i++)

#270 {

#271 dest = (BYTE*)(((DWORD)dest + 3) & ~3);

#272 ibtn[i] = (DLGITEMTEMPLATE *)dest;

#273 ibtn[i]->style = WS_CHILD | WS_VISIBLE | WS_TABSTOP;

#274 if(!defbtn && (i == ((lpMsgBoxParams->dwStyle & MB_DEFMASK) >> 8)))

#275 {

#276 ibtn[i]->style |= BS_DEFPUSHBUTTON;

#277 mbi.DefBtn = Buttons[i];

#278 defbtn = TRUE;

#279 }

#280 else

#281 ibtn[i]->style |= BS_PUSHBUTTON;

#282 ibtn[i]->dwExtendedStyle = 0;

#283 ibtn[i]->id = Buttons[i];

#284 dest += sizeof(DLGITEMTEMPLATE);

#285 *(WORD*)dest = 0xFFFF;

#286 dest += sizeof(WORD);

#287 *(WORD*)dest = 0x0080; /* button control */

#288 dest += sizeof(WORD);

#289 btnlen = strlenW(ButtonText[i]);

#290 memcpy(dest,btnlen * sizeof(WCHAR));

#291 dest += btnlen * sizeof(WCHAR);

#292 *(WORD*)dest = 0;

#293 dest += sizeof(WORD);

#294 *(WORD*)dest = 0;

#295 dest += sizeof(WORD);

#296 SelectObject(hDC,hFont);

显示按钮的字符串。

#297 DrawTextW(hDC,&btnrect,DT_LEFT | DT_SINGLELINE | DT_CALCRECT);

#298 btnsize.cx = max(btnsize.cx,btnrect.right);

#299 btnsize.cy = max(btnsize.cy,btnrect.bottom);

#300 }

#301

如果有按钮,就设置第一个为缺省选中按钮。

#302 /* make first button the default button if no other is */

#303 if(!defbtn)

#304 {

#305 ibtn[0]->style &= ~BS_PUSHBUTTON;

#306 ibtn[0]->style |= BS_DEFPUSHBUTTON;

#307 mbi.DefBtn = Buttons[0];

#308 }

#309

计算位置和窗口显示的大小。

#310 /* calculate position and size of controls */

#311 txtrect.right = GetSystemMetrics(SM_CXSCREEN) / 5 * 4;

#312 if(Icon)

#313 txtrect.right -= GetSystemMetrics(SM_CXICON) + MSGBoxEX_SPACING;

#314 txtrect.top = txtrect.left = txtrect.bottom = 0;

#315 SelectObject(hDC,hFont);

#316 if (textlen != 0)

#317 {

#318 DrawTextW(hDC,&txtrect,DT_LEFT | DT_NOPREFIX | DT_WORDBREAK | DT_CALCRECT);

#319 }

#320 else

#321 {

#322 txtrect.right = txtrect.left + 1;

#323 txtrect.bottom = txtrect.top + 1;

#324 }

#325 txtrect.right++;

#326

计算图标显示的位置和大小。

#327 /* calculate position and size of the icon */

#328 rc.left = rc.bottom = rc.right = 0;

#329 btntop = 0;

#330

#331 if(iico)

#332 {

#333 rc.right = GetSystemMetrics(SM_CXICON);

#334 rc.bottom = GetSystemMetrics(SM_CYICON);

#335 #ifdef MSGBox_ICONVCENTER

#336 rc.top = MSGBoxEX_MARGIN + (max(txtrect.bottom,rc.bottom) / 2) - (GetSystemMetrics(SM_CYICON) / 2);

#337 rc.top = max(MSGBoxEX_SPACING,rc.top);

#338 #else

#339 rc.top = MSGBoxEX_MARGIN;

#340 #endif

#341 btnleft = (nButtons * (btnsize.cx + MSGBoxEX_BUTTONSPACING)) - MSGBoxEX_BUTTONSPACING;

#342 if(btnleft > txtrect.right + rc.right + MSGBoxEX_SPACING)

#343 {

#344 #ifdef MSGBox_TEXTHCENTER

#345 lmargin = MSGBoxEX_MARGIN + ((btnleft - txtrect.right - rc.right - MSGBoxEX_SPACING) / 2);

#346 #else

#347 lmargin = MSGBoxEX_MARGIN;

#348 #endif

#349 btnleft = MSGBoxEX_MARGIN;

#350 }

#351 else

#352 {

#353 lmargin = MSGBoxEX_MARGIN;

#354 btnleft = MSGBoxEX_MARGIN + ((txtrect.right + rc.right + MSGBoxEX_SPACING) / 2) - (btnleft / 2);

#355 }

#356 rc.left = lmargin;

#357 iico->x = (rc.left * 4) / LOWORD(units);

#358 iico->y = (rc.top * 8) / HIWORD(units);

#359 iico->cx = (rc.right * 4) / LOWORD(units);

#360 iico->cy = (rc.bottom * 8) / HIWORD(units);

#361 btntop = rc.top + rc.bottom + MSGBoxEX_SPACING;

#362 rc.left += rc.right + MSGBoxEX_SPACING;

#363 }

#364 else

#365 {

#366 btnleft = (nButtons * (btnsize.cx + MSGBoxEX_BUTTONSPACING)) - MSGBoxEX_BUTTONSPACING;

#367 if(btnleft > txtrect.right)

#368 {

#369 #ifdef MSGBox_TEXTHCENTER

#370 lmargin = MSGBoxEX_MARGIN + ((btnleft - txtrect.right) / 2);

#371 #else

#372 lmargin = MSGBoxEX_MARGIN;

#373 #endif

#374 btnleft = MSGBoxEX_MARGIN;

#375 }

#376 else

#377 {

#378 lmargin = MSGBoxEX_MARGIN;

#379 btnleft = MSGBoxEX_MARGIN + (txtrect.right / 2) - (btnleft / 2);

#380 }

#381 rc.left = lmargin;

#382 }

计算按钮显示位置。

#383 /* calculate position of the text */

#384 rc.top = MSGBoxEX_MARGIN + (rc.bottom / 2) - (txtrect.bottom / 2);

#385 rc.top = max(rc.top,MSGBoxEX_MARGIN);

#386 /* calculate position of the buttons */

#387 btntop = max(rc.top + txtrect.bottom + MSGBoxEX_SPACING,btntop);

#388 for(i = 0; i < nButtons; i++)

#389 {

#390 ibtn[i]->x = (btnleft * 4) / LOWORD(units);

#391 ibtn[i]->y = (btntop * 8) / HIWORD(units);

#392 ibtn[i]->cx = (btnsize.cx * 4) / LOWORD(units);

#393 ibtn[i]->cy = (btnsize.cy * 8) / HIWORD(units);

#394 btnleft += btnsize.cx + MSGBoxEX_BUTTONSPACING;

#395 }

计算消息窗口的大小和位置。

#396 /* calculate size and position of the messageBox window */

#397 btnleft = max(btnleft - MSGBoxEX_BUTTONSPACING,rc.left + txtrect.right);

#398 btnleft += MSGBoxEX_MARGIN;

#399 btntop += btnsize.cy + MSGBoxEX_MARGIN;

#400 /* set size and position of the message static */

#401 itxt->x = (rc.left * 4) / LOWORD(units);

#402 itxt->y = (rc.top * 8) / HIWORD(units);

#403 itxt->cx = (((btnleft - rc.left - MSGBoxEX_MARGIN) * 4) / LOWORD(units));

#404 itxt->cy = ((txtrect.bottom * 8) / HIWORD(units));

#405 /* set size of the window */

#406 tpl->cx = (btnleft * 4) / LOWORD(units);

#407 tpl->cy = (btntop * 8) / HIWORD(units);

#408

填写下面的结构,并调用函数DialogBoxIndirectParamW显示对话框窗口,MessageBoxProc作为对话框的消息处理函数

#409 /* finally show the messageBox */

#410 mbi.Icon = Icon;

#411 mbi.Font = hFont;

#412 mbi.ContextHelpId = lpMsgBoxParams->dwContextHelpId;

#413 mbi.Callback = lpMsgBoxParams->lpfnMsgBoxCallback;

#414 mbi.Style = lpMsgBoxParams->dwStyle;

#415 mbi.nButtons = nButtons;

#416 mbi.Btns = &Buttons[0];

#417 mbi.Timeout = Timeout;

#418

#419 if(hDC)

#420 DeleteDC(hDC);

#421

#422 ret = DialogBoxIndirectParamW(lpMsgBoxParams->hInstance,tpl,lpMsgBoxParams->hwndOwner,

#423 MessageBoxProc,(LPARAM)&mbi);

#424

#425 if(hFont)

#426 DeleteObject(hFont);

#427

#428 RtlFreeHeap(GetProcessHeap(),buf);

#429 return ret;

#430}

原文链接:https://www.f2er.com/react/308344.html

猜你在找的React相关文章