4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #define RSF_WHOLESTRING 0x00000001
23 #define RSF_LOOKATKEYS 0x00000002
24 #define RSF_LOOKATVALUES 0x00000004
25 #define RSF_LOOKATDATA 0x00000008
26 #define RSF_MATCHCASE 0x00010000
28 static TCHAR s_szFindWhat
[256];
29 static const TCHAR s_szFindFlags
[] = _T("FindFlags");
30 static const TCHAR s_szFindFlagsR
[] = _T("FindFlagsReactOS");
31 static HWND s_hwndAbortDialog
;
34 static DWORD s_dwFlags
;
35 static TCHAR s_szName
[MAX_PATH
];
36 static DWORD s_cbName
;
37 static const TCHAR s_empty
[] = {0};
38 static const TCHAR s_backslash
[] = {'\\', 0};
40 extern VOID
SetValueName(HWND hwndLV
, LPCTSTR pszValueName
);
45 if (PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
))
47 if (msg
.message
== WM_QUIT
)
49 if (!IsDialogMessage(s_hwndAbortDialog
, &msg
))
51 TranslateMessage(&msg
);
52 DispatchMessage(&msg
);
58 static LPTSTR
lstrstri(LPCTSTR psz1
, LPCTSTR psz2
)
64 for(i
= 0; i
<= cch1
- cch2
; i
++)
66 if (CompareString(LOCALE_SYSTEM_DEFAULT
, NORM_IGNORECASE
,
67 psz1
+ i
, cch2
, psz2
, cch2
) == 2)
68 return (LPTSTR
) (psz1
+ i
);
73 static BOOL
CompareName(LPCTSTR pszName1
, LPCTSTR pszName2
)
75 if (s_dwFlags
& RSF_WHOLESTRING
)
77 if (s_dwFlags
& RSF_MATCHCASE
)
78 return lstrcmp(pszName1
, pszName2
) == 0;
80 return lstrcmpi(pszName1
, pszName2
) == 0;
84 if (s_dwFlags
& RSF_MATCHCASE
)
85 return _tcsstr(pszName1
, pszName2
) != NULL
;
87 return lstrstri(pszName1
, pszName2
) != NULL
;
97 INT i
, cch1
= lstrlen(psz1
), cch2
= lstrlen(psz2
);
98 if (dwType
== REG_SZ
|| dwType
== REG_EXPAND_SZ
)
100 if (s_dwFlags
& RSF_WHOLESTRING
)
102 if (s_dwFlags
& RSF_MATCHCASE
)
103 return 2 == CompareString(LOCALE_SYSTEM_DEFAULT
, 0,
104 psz1
, cch1
, psz2
, cch2
);
106 return 2 == CompareString(LOCALE_SYSTEM_DEFAULT
,
107 NORM_IGNORECASE
, psz1
, cch1
, psz2
, cch2
);
110 for(i
= 0; i
<= cch1
- cch2
; i
++)
112 if (s_dwFlags
& RSF_MATCHCASE
)
114 if (2 == CompareString(LOCALE_SYSTEM_DEFAULT
, 0,
115 psz1
+ i
, cch2
, psz2
, cch2
))
120 if (2 == CompareString(LOCALE_SYSTEM_DEFAULT
,
121 NORM_IGNORECASE
, psz1
+ i
, cch2
, psz2
, cch2
))
129 int compare(const void *x
, const void *y
)
131 const LPCTSTR
*a
= (const LPCTSTR
*)x
;
132 const LPCTSTR
*b
= (const LPCTSTR
*)y
;
133 return lstrcmpi(*a
, *b
);
139 LPCTSTR pszValueName
,
140 LPTSTR
*ppszFoundSubKey
,
141 LPTSTR
*ppszFoundValueName
)
145 TCHAR szSubKey
[MAX_PATH
];
146 DWORD i
, c
, cb
, type
;
148 LPTSTR
*ppszNames
= NULL
;
154 lstrcpy(szSubKey
, pszSubKey
);
157 lResult
= RegOpenKeyEx(hKey
, szSubKey
, 0, KEY_ALL_ACCESS
, &hSubKey
);
158 if (lResult
!= ERROR_SUCCESS
)
161 if (pszValueName
== NULL
)
162 pszValueName
= s_empty
;
164 lResult
= RegQueryInfoKey(hSubKey
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
165 &c
, NULL
, NULL
, NULL
, NULL
);
166 if (lResult
!= ERROR_SUCCESS
)
168 ppszNames
= (LPTSTR
*) malloc(c
* sizeof(LPTSTR
));
169 if (ppszNames
== NULL
)
171 ZeroMemory(ppszNames
, c
* sizeof(LPTSTR
));
173 for(i
= 0; i
< c
; i
++)
178 s_cbName
= MAX_PATH
* sizeof(TCHAR
);
179 lResult
= RegEnumValue(hSubKey
, i
, s_szName
, &s_cbName
, NULL
, NULL
,
181 if (lResult
== ERROR_NO_MORE_ITEMS
)
186 if (lResult
!= ERROR_SUCCESS
)
188 if (s_cbName
>= MAX_PATH
* sizeof(TCHAR
))
191 ppszNames
[i
] = _tcsdup(s_szName
);
194 qsort(ppszNames
, c
, sizeof(LPTSTR
), compare
);
196 for(i
= 0; i
< c
; i
++)
201 if (!fPast
&& lstrcmpi(ppszNames
[i
], pszValueName
) == 0)
209 if ((s_dwFlags
& RSF_LOOKATVALUES
) &&
210 CompareName(ppszNames
[i
], s_szFindWhat
))
212 *ppszFoundSubKey
= _tcsdup(szSubKey
);
213 if (ppszNames
[i
][0] == 0)
214 *ppszFoundValueName
= NULL
;
216 *ppszFoundValueName
= _tcsdup(ppszNames
[i
]);
220 lResult
= RegQueryValueEx(hSubKey
, ppszNames
[i
], NULL
, &type
,
222 if (lResult
!= ERROR_SUCCESS
)
227 lResult
= RegQueryValueEx(hSubKey
, ppszNames
[i
], NULL
, &type
,
229 if (lResult
!= ERROR_SUCCESS
)
232 if ((s_dwFlags
& RSF_LOOKATDATA
) &&
233 CompareData(type
, (LPTSTR
) pb
, s_szFindWhat
))
235 *ppszFoundSubKey
= _tcsdup(szSubKey
);
236 if (ppszNames
[i
][0] == 0)
237 *ppszFoundValueName
= NULL
;
239 *ppszFoundValueName
= _tcsdup(ppszNames
[i
]);
246 if (ppszNames
!= NULL
)
248 for(i
= 0; i
< c
; i
++)
254 lResult
= RegQueryInfoKey(hSubKey
, NULL
, NULL
, NULL
, &c
, NULL
, NULL
,
255 NULL
, NULL
, NULL
, NULL
, NULL
);
256 if (lResult
!= ERROR_SUCCESS
)
258 ppszNames
= (LPTSTR
*) malloc(c
* sizeof(LPTSTR
));
259 if (ppszNames
== NULL
)
261 ZeroMemory(ppszNames
, c
* sizeof(LPTSTR
));
263 for(i
= 0; i
< c
; i
++)
268 s_cbName
= MAX_PATH
* sizeof(TCHAR
);
269 lResult
= RegEnumKeyEx(hSubKey
, i
, s_szName
, &s_cbName
, NULL
, NULL
,
271 if (lResult
== ERROR_NO_MORE_ITEMS
)
276 if (lResult
!= ERROR_SUCCESS
)
278 if (s_cbName
>= MAX_PATH
* sizeof(TCHAR
))
281 ppszNames
[i
] = _tcsdup(s_szName
);
284 qsort(ppszNames
, c
, sizeof(LPTSTR
), compare
);
286 for(i
= 0; i
< c
; i
++)
291 if ((s_dwFlags
& RSF_LOOKATKEYS
) &&
292 CompareName(ppszNames
[i
], s_szFindWhat
))
294 *ppszFoundSubKey
= malloc(
295 (lstrlen(szSubKey
) + lstrlen(ppszNames
[i
]) + 2) *
297 if (*ppszFoundSubKey
== NULL
)
301 lstrcpy(*ppszFoundSubKey
, szSubKey
);
302 lstrcatW(*ppszFoundSubKey
, s_backslash
);
305 **ppszFoundSubKey
= 0;
306 lstrcatW(*ppszFoundSubKey
, ppszNames
[i
]);
307 *ppszFoundValueName
= NULL
;
311 if (RegFindRecurse(hSubKey
, ppszNames
[i
], NULL
, ppszFoundSubKey
,
314 LPTSTR psz
= *ppszFoundSubKey
;
315 *ppszFoundSubKey
= malloc(
316 (lstrlen(szSubKey
) + lstrlen(psz
) + 2) * sizeof(TCHAR
));
317 if (*ppszFoundSubKey
== NULL
)
321 lstrcpy(*ppszFoundSubKey
, szSubKey
);
322 lstrcatW(*ppszFoundSubKey
, s_backslash
);
325 **ppszFoundSubKey
= 0;
326 lstrcatW(*ppszFoundSubKey
, psz
);
333 if (ppszNames
!= NULL
)
335 for(i
= 0; i
< c
; i
++)
340 RegCloseKey(hSubKey
);
344 if (ppszNames
!= NULL
)
346 for(i
= 0; i
< c
; i
++)
350 RegCloseKey(hSubKey
);
357 LPCTSTR pszValueName
,
358 LPTSTR
*ppszFoundSubKey
,
359 LPTSTR
*ppszFoundValueName
)
363 HKEY hBaseKey
, hSubKey
;
364 TCHAR szKeyName
[MAX_PATH
];
365 TCHAR szSubKey
[MAX_PATH
];
368 LPTSTR
*ppszNames
= NULL
;
371 if (RegFindRecurse(hBaseKey
, pszSubKey
, pszValueName
, ppszFoundSubKey
,
375 if (lstrlen(pszSubKey
) >= MAX_PATH
)
378 lstrcpy(szSubKey
, pszSubKey
);
379 while(szSubKey
[0] != 0)
384 pch
= _tcsrchr(szSubKey
, _T('\\'));
387 lstrcpy(szKeyName
, szSubKey
);
393 lstrcpyn(szKeyName
, pch
+ 1, MAX_PATH
);
395 lResult
= RegOpenKeyEx(hBaseKey
, szSubKey
, 0, KEY_ALL_ACCESS
,
397 if (lResult
!= ERROR_SUCCESS
)
401 lResult
= RegQueryInfoKey(hSubKey
, NULL
, NULL
, NULL
, &c
, NULL
, NULL
,
402 NULL
, NULL
, NULL
, NULL
, NULL
);
403 if (lResult
!= ERROR_SUCCESS
)
406 ppszNames
= (LPTSTR
*) malloc(c
* sizeof(LPTSTR
));
407 if (ppszNames
== NULL
)
409 ZeroMemory(ppszNames
, c
* sizeof(LPTSTR
));
411 for(i
= 0; i
< c
; i
++)
416 s_cbName
= MAX_PATH
* sizeof(TCHAR
);
417 lResult
= RegEnumKeyExW(hSubKey
, i
, s_szName
, &s_cbName
,
418 NULL
, NULL
, NULL
, NULL
);
419 if (lResult
== ERROR_NO_MORE_ITEMS
)
424 if (lResult
!= ERROR_SUCCESS
)
426 ppszNames
[i
] = _tcsdup(s_szName
);
429 qsort(ppszNames
, c
, sizeof(LPTSTR
), compare
);
432 for(i
= 0; i
< c
; i
++)
437 if (!fPast
&& lstrcmpi(ppszNames
[i
], szKeyName
) == 0)
445 if ((s_dwFlags
& RSF_LOOKATKEYS
) &&
446 CompareName(ppszNames
[i
], s_szFindWhat
))
448 *ppszFoundSubKey
= malloc(
449 (lstrlen(szSubKey
) + lstrlen(ppszNames
[i
]) + 2) *
451 if (*ppszFoundSubKey
== NULL
)
455 lstrcpy(*ppszFoundSubKey
, szSubKey
);
456 lstrcatW(*ppszFoundSubKey
, s_backslash
);
459 **ppszFoundSubKey
= 0;
460 lstrcatW(*ppszFoundSubKey
, ppszNames
[i
]);
461 *ppszFoundValueName
= NULL
;
465 if (RegFindRecurse(hSubKey
, ppszNames
[i
], NULL
,
466 ppszFoundSubKey
, ppszFoundValueName
))
468 LPTSTR psz
= *ppszFoundSubKey
;
469 *ppszFoundSubKey
= malloc(
470 (lstrlen(szSubKey
) + lstrlen(psz
) + 2) *
472 if (*ppszFoundSubKey
== NULL
)
476 lstrcpy(*ppszFoundSubKey
, szSubKey
);
477 lstrcatW(*ppszFoundSubKey
, s_backslash
);
480 **ppszFoundSubKey
= 0;
481 lstrcatW(*ppszFoundSubKey
, psz
);
486 if (ppszNames
!= NULL
)
488 for(i
= 0; i
< c
; i
++)
494 if (hBaseKey
!= hSubKey
)
495 RegCloseKey(hSubKey
);
498 if (*phKey
== HKEY_CLASSES_ROOT
)
500 *phKey
= HKEY_CURRENT_USER
;
501 if (RegFindRecurse(*phKey
, s_empty
, NULL
, ppszFoundSubKey
,
506 if (*phKey
== HKEY_CURRENT_USER
)
508 *phKey
= HKEY_LOCAL_MACHINE
;
509 if (RegFindRecurse(*phKey
, s_empty
, NULL
, ppszFoundSubKey
,
514 if (*phKey
== HKEY_LOCAL_MACHINE
)
517 if (RegFindRecurse(*phKey
, s_empty
, NULL
, ppszFoundSubKey
,
522 if (*phKey
== HKEY_USERS
)
524 *phKey
= HKEY_CURRENT_CONFIG
;
525 if (RegFindRecurse(*phKey
, s_empty
, NULL
, ppszFoundSubKey
,
531 if (ppszNames
!= NULL
)
533 for(i
= 0; i
< c
; i
++)
537 if (hBaseKey
!= hSubKey
)
538 RegCloseKey(hSubKey
);
542 if (ppszNames
!= NULL
)
544 for(i
= 0; i
< c
; i
++)
548 if (hBaseKey
!= hSubKey
)
549 RegCloseKey(hSubKey
);
554 static DWORD
GetFindFlags(void)
557 DWORD dwType
, dwValue
, cbData
;
558 DWORD dwFlags
= RSF_LOOKATKEYS
| RSF_LOOKATVALUES
| RSF_LOOKATDATA
;
560 if (RegOpenKey(HKEY_CURRENT_USER
, g_szGeneralRegKey
, &hKey
) == ERROR_SUCCESS
)
562 /* Retrieve flags from registry key */
563 cbData
= sizeof(dwValue
);
564 if (RegQueryValueEx(hKey
, s_szFindFlags
, NULL
, &dwType
, (LPBYTE
) &dwValue
, &cbData
) == ERROR_SUCCESS
)
566 if (dwType
== REG_DWORD
)
567 dwFlags
= (dwFlags
& ~0x0000FFFF) | ((dwValue
& 0x0000FFFF) << 0);
570 /* Retrieve ReactOS Regedit specific flags from registry key */
571 cbData
= sizeof(dwValue
);
572 if (RegQueryValueEx(hKey
, s_szFindFlagsR
, NULL
, &dwType
, (LPBYTE
) &dwValue
, &cbData
) == ERROR_SUCCESS
)
574 if (dwType
== REG_DWORD
)
575 dwFlags
= (dwFlags
& ~0xFFFF0000) | ((dwValue
& 0x0000FFFF) << 16);
583 static void SetFindFlags(DWORD dwFlags
)
589 if (RegCreateKeyEx(HKEY_CURRENT_USER
, g_szGeneralRegKey
, 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &hKey
, &dwDisposition
) == ERROR_SUCCESS
)
591 dwData
= (dwFlags
>> 0) & 0x0000FFFF;
592 RegSetValueEx(hKey
, s_szFindFlags
, 0, REG_DWORD
, (const BYTE
*) &dwData
, sizeof(dwData
));
594 dwData
= (dwFlags
>> 16) & 0x0000FFFF;
595 RegSetValueEx(hKey
, s_szFindFlagsR
, 0, REG_DWORD
, (const BYTE
*) &dwData
, sizeof(dwData
));
601 static INT_PTR CALLBACK
AbortFindDialogProc(HWND hDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
603 UNREFERENCED_PARAMETER(lParam
);
604 UNREFERENCED_PARAMETER(hDlg
);
613 switch(HIWORD(wParam
))
616 switch(LOWORD(wParam
))
629 BOOL
FindNext(HWND hWnd
)
634 TCHAR szFullKey
[512];
635 LPCTSTR pszValueName
;
636 LPTSTR pszFoundSubKey
, pszFoundValueName
;
638 if (_tcslen(s_szFindWhat
) == 0)
644 s_dwFlags
= GetFindFlags();
646 pszKeyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
647 if (pszKeyPath
== NULL
)
649 hKeyRoot
= HKEY_CLASSES_ROOT
;
650 pszKeyPath
= s_empty
;
653 /* Create abort find dialog */
654 s_hwndAbortDialog
= CreateDialog(GetModuleHandle(NULL
),
655 MAKEINTRESOURCE(IDD_FINDING
), hWnd
, AbortFindDialogProc
);
656 if (s_hwndAbortDialog
)
658 ShowWindow(s_hwndAbortDialog
, SW_SHOW
);
659 UpdateWindow(s_hwndAbortDialog
);
663 pszValueName
= GetValueName(g_pChildWnd
->hListWnd
, -1);
665 EnableWindow(hFrameWnd
, FALSE
);
666 EnableWindow(g_pChildWnd
->hTreeWnd
, FALSE
);
667 EnableWindow(g_pChildWnd
->hListWnd
, FALSE
);
668 EnableWindow(g_pChildWnd
->hAddressBarWnd
, FALSE
);
670 fSuccess
= RegFindWalk(&hKeyRoot
, pszKeyPath
, pszValueName
,
671 &pszFoundSubKey
, &pszFoundValueName
);
673 EnableWindow(hFrameWnd
, TRUE
);
674 EnableWindow(g_pChildWnd
->hTreeWnd
, TRUE
);
675 EnableWindow(g_pChildWnd
->hListWnd
, TRUE
);
676 EnableWindow(g_pChildWnd
->hAddressBarWnd
, TRUE
);
678 if (s_hwndAbortDialog
)
680 DestroyWindow(s_hwndAbortDialog
);
681 s_hwndAbortDialog
= NULL
;
686 GetKeyName(szFullKey
, COUNT_OF(szFullKey
), hKeyRoot
, pszFoundSubKey
);
687 SelectNode(g_pChildWnd
->hTreeWnd
, szFullKey
);
688 SetValueName(g_pChildWnd
->hListWnd
, pszFoundValueName
);
689 free(pszFoundSubKey
);
690 free(pszFoundValueName
);
691 SetFocus(g_pChildWnd
->hListWnd
);
693 return fSuccess
|| s_bAbort
;
696 static INT_PTR CALLBACK
FindDialogProc(HWND hDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
702 static TCHAR s_szSavedFindValue
[256];
707 dwFlags
= GetFindFlags();
709 hControl
= GetDlgItem(hDlg
, IDC_LOOKAT_KEYS
);
711 SendMessage(hControl
, BM_SETCHECK
, (dwFlags
& RSF_LOOKATKEYS
) ? TRUE
: FALSE
, 0);
713 hControl
= GetDlgItem(hDlg
, IDC_LOOKAT_VALUES
);
715 SendMessage(hControl
, BM_SETCHECK
, (dwFlags
& RSF_LOOKATVALUES
) ? TRUE
: FALSE
, 0);
717 hControl
= GetDlgItem(hDlg
, IDC_LOOKAT_DATA
);
719 SendMessage(hControl
, BM_SETCHECK
, (dwFlags
& RSF_LOOKATDATA
) ? TRUE
: FALSE
, 0);
721 /* Match whole string */
722 hControl
= GetDlgItem(hDlg
, IDC_MATCHSTRING
);
724 SendMessage(hControl
, BM_SETCHECK
, (dwFlags
& RSF_WHOLESTRING
) ? TRUE
: FALSE
, 0);
726 /* Case sensitivity */
727 hControl
= GetDlgItem(hDlg
, IDC_MATCHCASE
);
729 SendMessage(hControl
, BM_SETCHECK
, (dwFlags
& RSF_MATCHCASE
) ? TRUE
: FALSE
, 0);
731 hControl
= GetDlgItem(hDlg
, IDC_FINDWHAT
);
734 SetWindowText(hControl
, s_szSavedFindValue
);
736 SendMessage(hControl
, EM_SETSEL
, 0, -1);
745 switch(HIWORD(wParam
))
748 switch(LOWORD(wParam
))
753 hControl
= GetDlgItem(hDlg
, IDC_LOOKAT_KEYS
);
754 if (hControl
&& (SendMessage(hControl
, BM_GETCHECK
, 0, 0) == BST_CHECKED
))
755 dwFlags
|= RSF_LOOKATKEYS
;
757 hControl
= GetDlgItem(hDlg
, IDC_LOOKAT_VALUES
);
758 if (hControl
&& (SendMessage(hControl
, BM_GETCHECK
, 0, 0) == BST_CHECKED
))
759 dwFlags
|= RSF_LOOKATVALUES
;
761 hControl
= GetDlgItem(hDlg
, IDC_LOOKAT_DATA
);
762 if (hControl
&& (SendMessage(hControl
, BM_GETCHECK
, 0, 0) == BST_CHECKED
))
763 dwFlags
|= RSF_LOOKATDATA
;
765 hControl
= GetDlgItem(hDlg
, IDC_MATCHSTRING
);
766 if (hControl
&& (SendMessage(hControl
, BM_GETCHECK
, 0, 0) == BST_CHECKED
))
767 dwFlags
|= RSF_WHOLESTRING
;
769 hControl
= GetDlgItem(hDlg
, IDC_MATCHCASE
);
770 if (hControl
&& (SendMessage(hControl
, BM_GETCHECK
, 0, 0) == BST_CHECKED
))
771 dwFlags
|= RSF_MATCHCASE
;
773 SetFindFlags(dwFlags
);
775 hControl
= GetDlgItem(hDlg
, IDC_FINDWHAT
);
777 GetWindowText(hControl
, s_szFindWhat
, sizeof(s_szFindWhat
) / sizeof(s_szFindWhat
[0]));
788 switch(LOWORD(wParam
))
791 GetWindowText((HWND
) lParam
, s_szSavedFindValue
, sizeof(s_szSavedFindValue
) / sizeof(s_szSavedFindValue
[0]));
792 hControl
= GetDlgItem(hDlg
, IDOK
);
795 lStyle
= GetWindowLongPtr(hControl
, GWL_STYLE
);
796 if (s_szSavedFindValue
[0])
797 lStyle
&= ~WS_DISABLED
;
799 lStyle
|= WS_DISABLED
;
800 SetWindowLongPtr(hControl
, GWL_STYLE
, lStyle
);
801 RedrawWindow(hControl
, NULL
, NULL
, RDW_INVALIDATE
);
811 void FindDialog(HWND hWnd
)
813 if (DialogBoxParam(GetModuleHandle(NULL
), MAKEINTRESOURCE(IDD_FIND
),
814 hWnd
, FindDialogProc
, 0) != 0)
818 TCHAR msg
[128], caption
[128];
820 LoadString(hInst
, IDS_FINISHEDFIND
, msg
, sizeof(msg
)/sizeof(TCHAR
));
821 LoadString(hInst
, IDS_APP_TITLE
, caption
, sizeof(caption
)/sizeof(TCHAR
));
822 MessageBox(0, msg
, caption
, MB_ICONINFORMATION
);