wininet: Don't discard the extra info part of a URL in InternetOpenUrl.
[wine] / programs / oleview / oleview.c
1 /*
2  * OleView (oleview.c)
3  *
4  * Copyright 2006 Piotr Caban
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include "main.h"
22
23 GLOBALS globals;
24 static WCHAR wszRegEdit[] = { 'r','e','g','e','d','i','t','.','e','x','e','\0' };
25 static WCHAR wszFormat[] = { '<','o','b','j','e','c','t','\n',' ',' ',' ',
26     'c','l','a','s','s','i','d','=','\"','c','l','s','i','d',':','%','s','\"','\n',
27     '>','\n','<','/','o','b','j','e','c','t','>','\0' };
28 WCHAR wszFilter[] = { 'T','y','p','e','L','i','b',' ','F','i','l','e','s',' ',
29     '(','*','t','l','b',';','*','o','l','b',';','*','.','d','l','l',';',
30     '*','.','o','c','x',';','*','.','e','x','e',')','\0',
31     '*','.','t','l','b',';','*','.','o','l','b',';','*','.','d','l','l',';',
32     '*','.','o','c','x','*','.','e','x','e','\0',
33     'A','l','l',' ','F','i','l','e','s',' ','(','*','.','*',')','\0',
34     '*','.','*','\0','\0' };
35
36 INT_PTR CALLBACK SysConfProc(HWND hDlgWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
37 {
38     HKEY hKey;
39     WCHAR buffer[MAX_LOAD_STRING];
40     DWORD bufSize;
41
42     WCHAR wszReg[] = { 'S','o','f','t','w','a','r','e','\\',
43         'M','i','c','r','o','s','o','f','t','\\','O','L','E','\\','\0' };
44     WCHAR wszEnableDCOM[] = { 'E','n','a','b','l','e','D','C','O','M','\0' };
45     WCHAR wszEnableRemote[] = { 'E','n','a','b','l','e',
46         'R','e','m','o','t','e','C','o','n','n','e','c','t','\0' };
47     WCHAR wszYes[] = { 'Y', '\0' };
48     WCHAR wszNo[] = { 'N', '\0' };
49
50     switch(uMsg)
51     {
52         case WM_INITDIALOG:
53             if(RegOpenKey(HKEY_LOCAL_MACHINE, wszReg, &hKey) != ERROR_SUCCESS)
54                 RegCreateKey(HKEY_LOCAL_MACHINE, wszReg, &hKey);
55
56             bufSize = sizeof(buffer);
57             if(RegGetValue(hKey, NULL, wszEnableDCOM, RRF_RT_REG_SZ,
58                         NULL, buffer, &bufSize) != ERROR_SUCCESS)
59             {
60                 bufSize = sizeof(wszYes);
61                 RegSetValueEx(hKey, wszEnableDCOM, 0, REG_SZ, (BYTE*)wszYes, bufSize);
62             }
63
64             CheckDlgButton(hDlgWnd, IDC_ENABLEDCOM,
65                     buffer[0]=='Y' ? BST_CHECKED : BST_UNCHECKED);
66
67             bufSize = sizeof(buffer);
68             if(RegGetValue(hKey, NULL, wszEnableRemote, RRF_RT_REG_SZ,
69                         NULL, buffer, &bufSize) != ERROR_SUCCESS)
70             {
71                 bufSize = sizeof(wszYes);
72                 RegSetValueEx(hKey, wszEnableRemote, 0, REG_SZ, (BYTE*)wszYes, bufSize);
73             }
74
75             CheckDlgButton(hDlgWnd, IDC_ENABLEREMOTE,
76                     buffer[0]=='Y' ? BST_CHECKED : BST_UNCHECKED);
77             
78             RegCloseKey(hKey);
79             return TRUE;
80         case WM_COMMAND:
81             switch(LOWORD(wParam)) {
82             case IDOK:
83                 bufSize = sizeof(wszYes);
84
85                 RegOpenKey(HKEY_LOCAL_MACHINE, wszReg, &hKey);
86
87                 RegSetValueEx(hKey, wszEnableDCOM, 0, REG_SZ,
88                         IsDlgButtonChecked(hDlgWnd, IDC_ENABLEDCOM) == BST_CHECKED ?
89                         (BYTE*)wszYes : (BYTE*)wszNo, bufSize);
90
91                 RegSetValueEx(hKey, wszEnableRemote, 0, REG_SZ,
92                         IsDlgButtonChecked(hDlgWnd, IDC_ENABLEREMOTE) == BST_CHECKED ?
93                         (BYTE*)wszYes : (BYTE*)wszNo, bufSize);
94
95                 RegCloseKey(hKey);
96
97                 EndDialog(hDlgWnd, IDOK);
98                 return TRUE;
99             case IDCANCEL:
100                 EndDialog(hDlgWnd, IDCANCEL);
101                 return TRUE;
102             }
103     }
104
105     return FALSE;
106 }
107
108 INT_PTR CALLBACK CreateInstOnProc(HWND hDlgWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
109 {
110     HWND hEdit;
111
112     switch(uMsg)
113     {
114         case WM_COMMAND:
115             switch(LOWORD(wParam)) {
116             case IDOK:
117                 memset(globals.wszMachineName, 0, sizeof(WCHAR[MAX_LOAD_STRING]));
118                 hEdit = GetDlgItem(hDlgWnd, IDC_MACHINE);
119
120                 if (GetWindowTextLength(hEdit)>0)
121                     GetWindowText(hEdit, globals.wszMachineName, MAX_LOAD_STRING);
122
123                 EndDialog(hDlgWnd, IDOK);
124                 return TRUE;
125             case IDCANCEL:
126                 EndDialog(hDlgWnd, IDCANCEL);
127                 return TRUE;
128             }
129     }
130
131     return FALSE;
132 }
133
134 void InitOpenFileName(HWND hWnd, OPENFILENAME *pofn, WCHAR *wszFilter,
135         WCHAR *wszTitle, WCHAR *wszFileName)
136 {
137     memset(pofn, 0, sizeof(OPENFILENAME));
138     pofn->lStructSize = sizeof(OPENFILENAME);
139     pofn->hwndOwner = hWnd;
140     pofn->hInstance = globals.hMainInst;
141
142     pofn->lpstrTitle = wszTitle;
143     pofn->lpstrFilter = wszFilter;
144     pofn->nFilterIndex = 0;
145     pofn->lpstrFile = wszFileName;
146     pofn->nMaxFile = MAX_LOAD_STRING;
147     pofn->Flags = OFN_HIDEREADONLY;
148 }
149
150 void CopyClsid(HTREEITEM item)
151 {
152     TVITEM tvi;
153
154     memset(&tvi, 0, sizeof(TVITEM));
155     tvi.hItem = item;
156     tvi.cchTextMax = MAX_LOAD_STRING;
157     SendMessage(globals.hTree, TVM_GETITEM, 0, (LPARAM)&tvi);
158
159     if(OpenClipboard(globals.hMainWnd) && EmptyClipboard() && tvi.lParam)
160     {
161         HANDLE hClipData = GlobalAlloc(GHND, sizeof(WCHAR[MAX_LOAD_STRING]));
162         LPVOID pLoc = GlobalLock(hClipData);
163
164         lstrcpyW(pLoc, ((ITEM_INFO *)tvi.lParam)->clsid);
165         GlobalUnlock(hClipData);
166         hClipData = SetClipboardData(CF_UNICODETEXT, hClipData);
167         CloseClipboard();
168     }
169 }
170
171 void CopyHTMLTag(HTREEITEM item)
172 {
173     TVITEM tvi;
174
175     memset(&tvi, 0, sizeof(TVITEM));
176     tvi.hItem = item;
177     tvi.cchTextMax = MAX_LOAD_STRING;
178     SendMessage(globals.hTree, TVM_GETITEM, 0, (LPARAM)&tvi);
179
180     if(OpenClipboard(globals.hMainWnd) && EmptyClipboard() && tvi.lParam)
181     {
182         HANDLE hClipData = GlobalAlloc(GHND, sizeof(WCHAR[MAX_LOAD_STRING]));
183         LPVOID pLoc = GlobalLock(hClipData);
184         int clsidLen = lstrlenW(((ITEM_INFO *)tvi.lParam)->clsid)-1;
185
186         ((ITEM_INFO *)tvi.lParam)->clsid[clsidLen] = '\0';
187         wsprintfW(pLoc, wszFormat, ((ITEM_INFO *)tvi.lParam)->clsid+1);
188         ((ITEM_INFO *)tvi.lParam)->clsid[clsidLen] = '}';
189
190         GlobalUnlock(hClipData);
191         hClipData = SetClipboardData(CF_UNICODETEXT, hClipData);
192         CloseClipboard();
193     }
194 }
195
196 void ResizeChild(void)
197 {
198     RECT client, stat, tool;
199
200     MoveWindow(globals.hStatusBar, 0, 0, 0, 0, TRUE);
201     MoveWindow(globals.hToolBar, 0, 0, 0, 0, TRUE);
202
203     if(IsWindowVisible(globals.hStatusBar))
204         GetClientRect(globals.hStatusBar, &stat);
205     else stat.bottom = 0;
206
207     if(IsWindowVisible(globals.hToolBar))
208     {
209         GetClientRect(globals.hToolBar, &tool);
210         tool.bottom += 2;
211     }
212     else tool.bottom = 0;
213
214     GetClientRect(globals.hMainWnd, &client);
215     MoveWindow(globals.hPaneWnd, 0, tool.bottom,
216             client.right, client.bottom-tool.bottom-stat.bottom, TRUE);
217 }
218
219 void RefreshMenu(HTREEITEM item)
220 {
221     TVITEM tvi;
222     HTREEITEM parent;
223     HMENU hMenu = GetMenu(globals.hMainWnd);
224
225     memset(&tvi, 0, sizeof(TVITEM));
226     tvi.hItem = item;
227     SendMessage(globals.hTree, TVM_GETITEM, 0, (LPARAM)&tvi);
228
229     parent = TreeView_GetParent(globals.hTree, item);
230
231     SendMessage(globals.hToolBar, TB_ENABLEBUTTON, IDM_CREATEINST, FALSE);
232     SendMessage(globals.hToolBar, TB_ENABLEBUTTON, IDM_RELEASEINST, FALSE);
233     SendMessage(globals.hToolBar, TB_ENABLEBUTTON, IDM_VIEW, FALSE);
234
235     if(tvi.lParam && ((ITEM_INFO *)tvi.lParam)->cFlag&SHOWALL)
236     {
237         EnableMenuItem(hMenu, IDM_COPYCLSID, MF_ENABLED);
238         EnableMenuItem(hMenu, IDM_HTMLTAG, MF_ENABLED);
239         EnableMenuItem(hMenu, IDM_VIEW, MF_GRAYED);
240
241         if(!((ITEM_INFO *)tvi.lParam)->loaded)
242         {
243             EnableMenuItem(hMenu, IDM_CREATEINST, MF_ENABLED);
244             EnableMenuItem(hMenu, IDM_CREATEINSTON, MF_ENABLED);
245             EnableMenuItem(hMenu, IDM_RELEASEINST, MF_GRAYED);
246             SendMessage(globals.hToolBar, TB_ENABLEBUTTON, IDM_CREATEINST, TRUE);
247         }
248         else 
249         {
250             EnableMenuItem(hMenu, IDM_CREATEINST, MF_GRAYED);
251             EnableMenuItem(hMenu, IDM_CREATEINSTON, MF_GRAYED);
252             EnableMenuItem(hMenu, IDM_RELEASEINST, MF_ENABLED);
253             SendMessage(globals.hToolBar, TB_ENABLEBUTTON, IDM_RELEASEINST, TRUE);
254         }
255     }
256     else if(tvi.lParam && 
257             (((ITEM_INFO *)tvi.lParam)->cFlag&INTERFACE || parent==tree.hTL))
258     {
259         EnableMenuItem(hMenu, IDM_TYPEINFO, MF_GRAYED);
260         EnableMenuItem(hMenu, IDM_CREATEINST, MF_GRAYED);
261         EnableMenuItem(hMenu, IDM_CREATEINSTON, MF_GRAYED);
262         EnableMenuItem(hMenu, IDM_RELEASEINST, MF_GRAYED);
263         EnableMenuItem(hMenu, IDM_COPYCLSID, MF_ENABLED);
264         EnableMenuItem(hMenu, IDM_HTMLTAG, MF_GRAYED);
265         EnableMenuItem(hMenu, IDM_VIEW, MF_ENABLED);
266         SendMessage(globals.hToolBar, TB_ENABLEBUTTON, IDM_VIEW, TRUE);
267     }
268     else
269     {
270         EnableMenuItem(hMenu, IDM_TYPEINFO, MF_GRAYED);
271         EnableMenuItem(hMenu, IDM_CREATEINST, MF_GRAYED);
272         EnableMenuItem(hMenu, IDM_CREATEINSTON, MF_GRAYED);
273         EnableMenuItem(hMenu, IDM_RELEASEINST, MF_GRAYED);
274         EnableMenuItem(hMenu, IDM_COPYCLSID, MF_GRAYED);
275         EnableMenuItem(hMenu, IDM_HTMLTAG, MF_GRAYED);
276         EnableMenuItem(hMenu, IDM_VIEW, MF_GRAYED);
277     }
278
279     if(parent==tree.hAID || parent==tree.hGBCC)
280         EnableMenuItem(hMenu, IDM_COPYCLSID, MF_ENABLED);
281 }
282
283 int MenuCommand(WPARAM wParam, HWND hWnd)
284 {
285     BOOL vis;
286     HTREEITEM hSelect;
287     WCHAR wszAbout[MAX_LOAD_STRING];
288     WCHAR wszAboutVer[MAX_LOAD_STRING];
289
290     switch(wParam)
291     {
292         case IDM_ABOUT:
293             LoadString(globals.hMainInst, IDS_ABOUT, wszAbout,
294                     sizeof(WCHAR[MAX_LOAD_STRING]));
295             LoadString(globals.hMainInst, IDS_ABOUTVER, wszAboutVer,
296                     sizeof(WCHAR[MAX_LOAD_STRING]));
297             ShellAbout(hWnd, wszAbout, wszAboutVer, NULL);
298             break;
299         case IDM_COPYCLSID:
300             hSelect = TreeView_GetSelection(globals.hTree);
301             CopyClsid(hSelect);
302             break;
303         case IDM_HTMLTAG:
304             hSelect = TreeView_GetSelection(globals.hTree);
305             CopyHTMLTag(hSelect);
306             break;
307         case IDM_CREATEINST:
308             hSelect = TreeView_GetSelection(globals.hTree);
309             CreateInst(hSelect, NULL);
310             SendMessage(globals.hTree, TVM_EXPAND, TVE_EXPAND, (LPARAM)hSelect);
311             break;
312         case IDM_CREATEINSTON:
313             if(DialogBox(0, MAKEINTRESOURCE(DLG_CREATEINSTON),
314                         hWnd, CreateInstOnProc) == IDCANCEL) break;
315             hSelect = TreeView_GetSelection(globals.hTree);
316             CreateInst(hSelect, globals.wszMachineName);
317             SendMessage(globals.hTree, TVM_EXPAND, TVE_EXPAND, (LPARAM)hSelect);
318             break;
319         case IDM_RELEASEINST:
320             hSelect = TreeView_GetSelection(globals.hTree);
321             ReleaseInst(hSelect);
322             RefreshMenu(hSelect);
323             RefreshDetails(hSelect);
324             break;
325         case IDM_EXPERT:
326             globals.bExpert = !globals.bExpert;
327             CheckMenuItem(GetMenu(hWnd), LOWORD(wParam),
328                     globals.bExpert ? MF_CHECKED : MF_UNCHECKED);
329             EmptyTree();
330             if(globals.bExpert) AddTreeEx();
331             else AddTree();
332             hSelect = TreeView_GetChild(globals.hTree, TVI_ROOT);
333             SendMessage(globals.hTree, TVM_SELECTITEM, 0, (LPARAM)hSelect);
334             RefreshMenu(hSelect);
335             break;
336         case IDM_FLAG_INSERV:
337             vis = globals.dwClsCtx&CLSCTX_INPROC_SERVER;
338             globals.dwClsCtx = globals.dwClsCtx&(~CLSCTX_INPROC_SERVER);
339             globals.dwClsCtx = globals.dwClsCtx|((~vis)&CLSCTX_INPROC_SERVER);
340             if(!globals.dwClsCtx) globals.dwClsCtx = vis;
341             else CheckMenuItem(GetMenu(hWnd), LOWORD(wParam),
342                     vis ? MF_UNCHECKED : MF_CHECKED);
343             break;
344         case IDM_FLAG_INHANDL:
345             vis = globals.dwClsCtx&CLSCTX_INPROC_HANDLER;
346             globals.dwClsCtx = globals.dwClsCtx&(~CLSCTX_INPROC_HANDLER);
347             globals.dwClsCtx = globals.dwClsCtx|((~vis)&CLSCTX_INPROC_HANDLER);
348             if(!globals.dwClsCtx) globals.dwClsCtx = vis;
349             else CheckMenuItem(GetMenu(hWnd), LOWORD(wParam),
350                     vis ? MF_UNCHECKED : MF_CHECKED);
351             break;
352         case IDM_FLAG_LOCSERV:
353             vis = globals.dwClsCtx&CLSCTX_LOCAL_SERVER;
354             globals.dwClsCtx = globals.dwClsCtx&(~CLSCTX_LOCAL_SERVER);
355             globals.dwClsCtx = globals.dwClsCtx|((~vis)&CLSCTX_LOCAL_SERVER);
356             if(!globals.dwClsCtx) globals.dwClsCtx = vis;
357             else CheckMenuItem(GetMenu(hWnd), LOWORD(wParam),
358                     vis ? MF_UNCHECKED : MF_CHECKED);
359             break;
360         case IDM_FLAG_REMSERV:
361             vis = globals.dwClsCtx&CLSCTX_REMOTE_SERVER;
362             globals.dwClsCtx = globals.dwClsCtx&(~CLSCTX_REMOTE_SERVER);
363             globals.dwClsCtx = globals.dwClsCtx|((~vis)&CLSCTX_REMOTE_SERVER);
364             if(!globals.dwClsCtx) globals.dwClsCtx = vis;
365             else CheckMenuItem(GetMenu(hWnd), LOWORD(wParam),
366                     vis ? MF_UNCHECKED : MF_CHECKED);
367             break;
368         case IDM_REFRESH:
369             EmptyTree();
370             if(globals.bExpert) AddTreeEx();
371             else AddTree();
372             hSelect = TreeView_GetChild(globals.hTree, TVI_ROOT);
373             SendMessage(globals.hTree, TVM_SELECTITEM, 0, (LPARAM)hSelect);
374             RefreshMenu(hSelect);
375             break;
376         case IDM_REGEDIT:
377         {
378             STARTUPINFO si;
379             PROCESS_INFORMATION pi;
380
381             memset(&si, 0, sizeof(si));
382             si.cb = sizeof(si);
383             CreateProcess(NULL, wszRegEdit, NULL, NULL, FALSE, 0,
384                     NULL, NULL, &si, &pi);
385             CloseHandle(pi.hProcess);
386             CloseHandle(pi.hThread);
387             break;
388         }
389         case IDM_STATUSBAR:
390             vis = IsWindowVisible(globals.hStatusBar);
391             ShowWindow(globals.hStatusBar, vis ? SW_HIDE : SW_SHOW);
392             CheckMenuItem(GetMenu(hWnd), LOWORD(wParam),
393                     vis ? MF_UNCHECKED : MF_CHECKED);
394             ResizeChild();
395             break;
396         case IDM_SYSCONF:
397             DialogBox(0, MAKEINTRESOURCE(DLG_SYSCONF), hWnd, SysConfProc);
398             break;
399         case IDM_TOOLBAR:
400             vis = IsWindowVisible(globals.hToolBar);
401             ShowWindow(globals.hToolBar, vis ? SW_HIDE : SW_SHOW);
402             CheckMenuItem(GetMenu(hWnd), LOWORD(wParam),
403                     vis ? MF_UNCHECKED : MF_CHECKED);
404             ResizeChild();
405             break;
406         case IDM_TYPELIB:
407             {
408             OPENFILENAME ofn;
409             static WCHAR wszTitle[MAX_LOAD_STRING];
410             static WCHAR wszName[MAX_LOAD_STRING];
411
412             LoadString(globals.hMainInst, IDS_OPEN, wszTitle, sizeof(wszTitle));
413             InitOpenFileName(hWnd, &ofn, wszFilter, wszTitle, wszName);
414             if(GetOpenFileName(&ofn)) CreateTypeLibWindow(globals.hMainInst, wszName);
415             break;
416             }
417         case IDM_VIEW:
418             hSelect = TreeView_GetSelection(globals.hTree);
419             if(IsInterface(hSelect)) InterfaceViewer(hSelect);
420             else CreateTypeLibWindow(globals.hMainInst, NULL);
421             break;
422         case IDM_EXIT:
423             DestroyWindow(hWnd);
424             break;
425     }
426     return 0;
427 }
428
429 void UpdateStatusBar(int itemID)
430 {
431     WCHAR info[MAX_LOAD_STRING];
432
433     if(!LoadString(globals.hMainInst, itemID, info, sizeof(WCHAR[MAX_LOAD_STRING])))
434         LoadString(globals.hMainInst, IDS_READY, info, sizeof(WCHAR[MAX_LOAD_STRING]));
435
436     SendMessage(globals.hStatusBar, SB_SETTEXT, 0, (LPARAM)info);
437 }
438
439 LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg,
440         WPARAM wParam, LPARAM lParam)
441 {
442     switch(uMsg)
443     {
444         case WM_CREATE:
445             OleInitialize(NULL);
446             PaneRegisterClass();
447             TypeLibRegisterClass();
448             if(!CreatePanedWindow(hWnd, &globals.hPaneWnd, globals.hMainInst))
449                 PostQuitMessage(0);
450             SetLeft(globals.hPaneWnd, CreateTreeWindow(globals.hMainInst));
451             SetRight(globals.hPaneWnd, CreateDetailsWindow(globals.hMainInst));
452             SetFocus(globals.hTree);
453             break;
454         case WM_COMMAND:
455             MenuCommand(LOWORD(wParam), hWnd);
456             break;
457         case WM_DESTROY:
458             OleUninitialize();
459             EmptyTree();
460             PostQuitMessage(0);
461             break;
462         case WM_MENUSELECT:
463             UpdateStatusBar(LOWORD(wParam));
464             break;
465         case WM_SETFOCUS:
466             SetFocus(globals.hTree);
467             break;
468         case WM_SIZE:
469             if(wParam == SIZE_MINIMIZED) break;
470             ResizeChild();
471             break;
472         default:
473             return DefWindowProc(hWnd, uMsg, wParam, lParam);
474     }
475     return 0;
476 }
477
478 BOOL InitApplication(HINSTANCE hInst)
479 {
480     WNDCLASS wc;
481     WCHAR wszAppName[MAX_LOAD_STRING];
482
483     LoadString(hInst, IDS_APPNAME, wszAppName, sizeof(WCHAR[MAX_LOAD_STRING]));
484
485     memset(&wc, 0, sizeof(WNDCLASS));
486     wc.lpfnWndProc = WndProc;
487     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
488     wc.lpszMenuName = MAKEINTRESOURCE(IDM_MENU);
489     wc.lpszClassName = wszAppName;
490
491     if(!RegisterClass(&wc))
492         return FALSE;
493
494     return TRUE;
495 }
496
497 BOOL InitInstance(HINSTANCE hInst, int nCmdShow)
498 {
499     HWND hWnd;
500     WCHAR wszAppName[MAX_LOAD_STRING];
501     WCHAR wszTitle[MAX_LOAD_STRING];
502     TBBUTTON tB[] = {
503         {0, 0, 0, BTNS_SEP, {0, 0}, 0, 0},
504         {0, IDM_BIND, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
505         {1, IDM_TYPELIB, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
506         {0, 0, 0, BTNS_SEP, {0, 0}, 0, 0},
507         {2, IDM_REGEDIT, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
508         {0, 0, 0, BTNS_SEP, {0, 0}, 0, 0},
509         {3, IDM_CREATEINST, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
510         {4, IDM_RELEASEINST, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
511         {0, 0, 0, BTNS_SEP, {0, 0}, 0, 0},
512         {5, IDM_VIEW, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0}
513     };
514
515     LoadString(hInst, IDS_APPNAME, wszAppName, sizeof(WCHAR[MAX_LOAD_STRING]));
516     LoadString(hInst, IDS_APPTITLE, wszTitle, sizeof(WCHAR[MAX_LOAD_STRING]));
517
518     hWnd = CreateWindow(wszAppName, wszTitle, WS_OVERLAPPEDWINDOW,
519             CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInst, NULL);
520     if(!hWnd) return FALSE;
521
522     globals.hStatusBar = CreateStatusWindow(WS_VISIBLE|WS_CHILD,
523             (LPWSTR)wszTitle, hWnd, 0);
524
525     globals.hToolBar = CreateToolbarEx(hWnd, WS_CHILD|WS_VISIBLE, 0, 1, hInst,
526             IDB_TOOLBAR, tB, 10, 16, 16, 16, 16, sizeof(TBBUTTON));
527     SendMessage(globals.hToolBar, TB_ENABLEBUTTON, IDM_CREATEINST, FALSE);
528     SendMessage(globals.hToolBar, TB_ENABLEBUTTON, IDM_RELEASEINST, FALSE);
529     SendMessage(globals.hToolBar, TB_ENABLEBUTTON, IDM_VIEW, FALSE);
530
531     globals.hMainWnd = hWnd;
532     globals.hMainInst = hInst;
533     globals.bExpert = TRUE;
534     globals.dwClsCtx = CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER;
535
536     ShowWindow(hWnd, nCmdShow);
537     UpdateWindow(hWnd);
538
539     return TRUE;
540 }
541
542 int APIENTRY wWinMain(HINSTANCE hInst, HINSTANCE hPrevInst,
543                 LPWSTR lpCmdLine, int nCmdShow)
544 {
545     MSG msg;
546     HANDLE hAccelTable;
547    
548     if(!hPrevInst)
549     {
550         if(!InitApplication(hInst))
551             return FALSE;
552     }
553
554     if(!InitInstance(hInst, nCmdShow))
555         return FALSE;
556
557     hAccelTable = LoadAccelerators(hInst, MAKEINTRESOURCE(IDA_OLEVIEW));
558
559     while(GetMessage(&msg, NULL, 0, 0))
560     {
561         if(TranslateAccelerator(globals.hMainWnd, hAccelTable, &msg)) continue;
562
563         TranslateMessage(&msg);
564         DispatchMessage(&msg);
565     }
566
567     return msg.wParam;
568 }