a99812edf0f447a4d9e317c3bf3909da48d088df
[reactos.git] / modules / rosapps / applications / devutils / vgafontedit / mainwnd.c
1 /*
2 * PROJECT: ReactOS VGA Font Editor
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Implements the main window of the application
5 * COPYRIGHT: Copyright 2008 Colin Finck (colin@reactos.org)
6 * Copyright 2018 Katayama Hirofui MZ (katayama.hirofumi.mz@gmail.com)
7 */
8
9 #include "precomp.h"
10
11 static const WCHAR szMainWndClass[] = L"VGAFontEditMainWndClass";
12
13 static VOID
14 InitResources(IN PMAIN_WND_INFO Info)
15 {
16 HDC hMemDC;
17 HDC hMainDC;
18 HPEN hPen, hPenOld;
19 RECT rect;
20 HBITMAP hBitmapOld;
21
22 hMemDC = CreateCompatibleDC(NULL);
23 hMainDC = GetDC(Info->hMainWnd);
24
25 // Create the "Box" bitmap
26 Info->hBoxBmp = CreateCompatibleBitmap(hMainDC, CHARACTER_BOX_WIDTH, CHARACTER_BOX_HEIGHT);
27 hBitmapOld = SelectObject(hMemDC, Info->hBoxBmp);
28
29 rect.left = 0;
30 rect.top = 0;
31 rect.right = CHARACTER_INFO_BOX_WIDTH;
32 rect.bottom = CHARACTER_INFO_BOX_HEIGHT;
33 FillRect( hMemDC, &rect, (HBRUSH)(COLOR_BTNFACE + 1) );
34
35 hPenOld = SelectObject( hMemDC, GetStockObject(WHITE_PEN) );
36 Rectangle(hMemDC, 0, 0, CHARACTER_INFO_BOX_WIDTH - 1, 2);
37 Rectangle(hMemDC, 0, 2, 2, CHARACTER_INFO_BOX_HEIGHT - 1);
38 hPen = SelectObject(hMemDC, hPenOld);
39
40 hPen = CreatePen( PS_SOLID, 1, RGB(128, 128, 128) );
41 hPenOld = SelectObject(hMemDC, hPen);
42 Rectangle(hMemDC, 1, CHARACTER_INFO_BOX_HEIGHT - 2, CHARACTER_INFO_BOX_WIDTH, CHARACTER_INFO_BOX_HEIGHT);
43 Rectangle(hMemDC, CHARACTER_INFO_BOX_WIDTH - 2, 1, CHARACTER_INFO_BOX_WIDTH, CHARACTER_INFO_BOX_HEIGHT - 2);
44
45 SetPixel( hMemDC, CHARACTER_INFO_BOX_WIDTH - 1, 0, RGB(128, 128, 128) );
46 SetPixel( hMemDC, 0, CHARACTER_INFO_BOX_HEIGHT - 1, RGB(128, 128, 128) );
47 SelectObject(hMemDC, hBitmapOld);
48
49 hPen = SelectObject(hMemDC, hPenOld);
50 DeleteObject(hPen);
51 DeleteDC(hMemDC);
52 ReleaseDC(Info->hMainWnd, hMainDC);
53 }
54
55 static VOID
56 UnInitResources(IN PMAIN_WND_INFO Info)
57 {
58 DeleteObject(Info->hBoxBmp);
59 }
60
61 static VOID
62 AddToolbarButton(IN PMAIN_WND_INFO Info, IN INT iBitmap, IN INT idCommand, IN UINT uID)
63 {
64 PWSTR pszTooltip;
65 TBBUTTON tbb = {0,};
66
67 if( AllocAndLoadString(&pszTooltip, uID) )
68 {
69 tbb.fsState = TBSTATE_ENABLED;
70 tbb.iBitmap = iBitmap;
71 tbb.idCommand = idCommand;
72 tbb.iString = (INT_PTR)pszTooltip;
73
74 SendMessageW( Info->hToolbar, TB_ADDBUTTONSW, 1, (LPARAM)&tbb );
75 HeapFree(hProcessHeap, 0, pszTooltip);
76 }
77 }
78
79 static VOID
80 SetToolbarButtonState(IN PMAIN_WND_INFO Info, INT idCommand, BOOL bEnabled)
81 {
82 TBBUTTONINFOW tbbi = {0,};
83
84 tbbi.cbSize = sizeof(tbbi);
85 tbbi.dwMask = TBIF_STATE;
86 tbbi.fsState = (bEnabled ? TBSTATE_ENABLED : 0);
87
88 SendMessageW(Info->hToolbar, TB_SETBUTTONINFOW, idCommand, (LPARAM)&tbbi);
89 }
90
91 VOID
92 SetToolbarFileButtonState(IN PMAIN_WND_INFO Info, BOOL bEnabled)
93 {
94 SetToolbarButtonState(Info, ID_FILE_SAVE, bEnabled);
95 SetToolbarButtonState(Info, ID_EDIT_GLYPH, bEnabled);
96 SetToolbarButtonState(Info, ID_EDIT_COPY, bEnabled);
97 }
98
99 static VOID
100 AddToolbarSeparator(IN PMAIN_WND_INFO Info)
101 {
102 TBBUTTON tbb = {0,};
103
104 tbb.fsStyle = BTNS_SEP;
105
106 SendMessageW( Info->hToolbar, TB_ADDBUTTONSW, 1, (LPARAM)&tbb );
107 }
108
109 static VOID
110 InitMainWnd(IN PMAIN_WND_INFO Info)
111 {
112 CLIENTCREATESTRUCT ccs;
113 INT iCustomBitmaps;
114 INT iStandardBitmaps;
115 TBADDBITMAP tbab;
116
117 // Add the toolbar
118 Info->hToolbar = CreateWindowExW(0,
119 TOOLBARCLASSNAMEW,
120 NULL,
121 WS_VISIBLE | WS_CHILD | TBSTYLE_TOOLTIPS,
122 0,
123 0,
124 0,
125 0,
126 Info->hMainWnd,
127 NULL,
128 hInstance,
129 NULL);
130
131 // Identify the used Common Controls version
132 SendMessageW(Info->hToolbar, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
133
134 // Enable Tooltips
135 SendMessageW(Info->hToolbar, TB_SETMAXTEXTROWS, 0, 0);
136
137 // Add the toolbar bitmaps
138 tbab.hInst = HINST_COMMCTRL;
139 tbab.nID = IDB_STD_SMALL_COLOR;
140 iStandardBitmaps = (INT)SendMessageW(Info->hToolbar, TB_ADDBITMAP, 0, (LPARAM)&tbab);
141
142 tbab.hInst = hInstance;
143 tbab.nID = IDB_MAIN_TOOLBAR;
144 iCustomBitmaps = (INT)SendMessageW(Info->hToolbar, TB_ADDBITMAP, 0, (LPARAM)&tbab);
145
146 // Add the toolbar buttons
147 AddToolbarButton(Info, iStandardBitmaps + STD_FILENEW, ID_FILE_NEW, IDS_TOOLTIP_NEW);
148 AddToolbarButton(Info, iStandardBitmaps + STD_FILEOPEN, ID_FILE_OPEN, IDS_TOOLTIP_OPEN);
149 AddToolbarButton(Info, iStandardBitmaps + STD_FILESAVE, ID_FILE_SAVE, IDS_TOOLTIP_SAVE);
150 AddToolbarSeparator(Info);
151 AddToolbarButton(Info, iCustomBitmaps + TOOLBAR_EDIT_GLYPH, ID_EDIT_GLYPH, IDS_TOOLTIP_EDIT_GLYPH);
152 AddToolbarSeparator(Info);
153 AddToolbarButton(Info, iStandardBitmaps + STD_COPY, ID_EDIT_COPY, IDS_TOOLTIP_COPY);
154 AddToolbarButton(Info, iStandardBitmaps + STD_PASTE, ID_EDIT_PASTE, IDS_TOOLTIP_PASTE);
155
156 SetToolbarFileButtonState(Info, FALSE);
157 SetPasteButtonState(Info);
158
159 // Add the MDI client area
160 ccs.hWindowMenu = GetSubMenu(Info->hMenu, 2);
161 ccs.idFirstChild = ID_MDI_FIRSTCHILD;
162
163 Info->hMdiClient = CreateWindowExW(WS_EX_CLIENTEDGE,
164 L"MDICLIENT",
165 NULL,
166 WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VSCROLL | WS_HSCROLL,
167 0,
168 0,
169 0,
170 0,
171 Info->hMainWnd,
172 NULL,
173 hInstance,
174 &ccs);
175
176 // Initialize the file handling
177 FileInitialize(Info->hMainWnd);
178 }
179
180 static VOID
181 InitMenuPopup(IN PMAIN_WND_INFO Info)
182 {
183 UINT uState;
184
185 uState = MF_BYCOMMAND | !(Info->CurrentFontWnd);
186
187 EnableMenuItem(Info->hMenu, ID_FILE_CLOSE, uState);
188 EnableMenuItem(Info->hMenu, ID_FILE_SAVE, uState);
189 EnableMenuItem(Info->hMenu, ID_FILE_SAVE_AS, uState);
190
191 EnableMenuItem(Info->hMenu, ID_EDIT_COPY, uState);
192 EnableMenuItem(Info->hMenu, ID_EDIT_GLYPH, uState);
193
194 uState = MF_BYCOMMAND | !(Info->CurrentFontWnd && IsClipboardFormatAvailable(uCharacterClipboardFormat));
195 EnableMenuItem(Info->hMenu, ID_EDIT_PASTE, uState);
196 }
197
198 static VOID
199 DoFileNew(IN PMAIN_WND_INFO Info)
200 {
201 PFONT_OPEN_INFO OpenInfo;
202
203 OpenInfo = (PFONT_OPEN_INFO) HeapAlloc( hProcessHeap, HEAP_ZERO_MEMORY, sizeof(FONT_OPEN_INFO) );
204 OpenInfo->bCreateNew = TRUE;
205
206 CreateFontWindow(Info, OpenInfo);
207 }
208
209 static VOID
210 DoFileOpen(IN PMAIN_WND_INFO Info)
211 {
212 PFONT_OPEN_INFO OpenInfo;
213
214 OpenInfo = (PFONT_OPEN_INFO) HeapAlloc( hProcessHeap, HEAP_ZERO_MEMORY, sizeof(FONT_OPEN_INFO) );
215 OpenInfo->pszFileName = HeapAlloc(hProcessHeap, 0, MAX_PATH);
216 if (OpenInfo->pszFileName)
217 {
218 OpenInfo->pszFileName[0] = 0;
219
220 if (DoOpenFile(OpenInfo->pszFileName))
221 {
222 OpenInfo->bCreateNew = FALSE;
223 CreateFontWindow(Info, OpenInfo);
224 }
225 else
226 {
227 HeapFree(hProcessHeap, 0, OpenInfo->pszFileName);
228 }
229 }
230 else
231 {
232 MessageBoxW(Info->hMainWnd, L"Out of memory!", NULL, MB_ICONERROR);
233 }
234 }
235
236 static VOID
237 MainWndOpenFile(IN PMAIN_WND_INFO Info, LPCWSTR File)
238 {
239 PFONT_OPEN_INFO OpenInfo;
240
241 OpenInfo = HeapAlloc(hProcessHeap, HEAP_ZERO_MEMORY, sizeof(FONT_OPEN_INFO));
242 OpenInfo->pszFileName = HeapAlloc(hProcessHeap, 0, MAX_PATH);
243 if (OpenInfo->pszFileName)
244 {
245 if (StringCchCopyW(OpenInfo->pszFileName, MAX_PATH, File) == S_OK)
246 {
247 OpenInfo->bCreateNew = FALSE;
248 CreateFontWindow(Info, OpenInfo);
249 }
250 else
251 {
252 MessageBoxW(Info->hMainWnd, L"Pathname is too long!", NULL, MB_ICONERROR);
253 HeapFree(hProcessHeap, 0, OpenInfo->pszFileName);
254 }
255 }
256 else
257 {
258 MessageBoxW(Info->hMainWnd, L"Out of memory!", NULL, MB_ICONERROR);
259 }
260 }
261
262 static VOID
263 MainWndDropFiles(IN PMAIN_WND_INFO Info, HDROP hDrop)
264 {
265 WCHAR Path[MAX_PATH];
266 INT i, Count = DragQueryFileW(hDrop, 0xFFFFFFFF, NULL, 0);
267
268 for (i = 0; i < Count; ++i)
269 {
270 DragQueryFileW(hDrop, i, Path, MAX_PATH);
271 MainWndOpenFile(Info, Path);
272 }
273
274 DragFinish(hDrop);
275 }
276
277 VOID
278 DoFileSave(IN PMAIN_WND_INFO Info, IN BOOL bSaveAs)
279 {
280 DWORD dwBytesWritten;
281 HANDLE hFile;
282
283 // Show the "Save" dialog
284 // - if "Save As" was clicked
285 // - if the file was not yet saved
286 // - if another format than the binary format was opened
287 if(bSaveAs || !Info->CurrentFontWnd->OpenInfo->bBinaryFileOpened)
288 {
289 if(!Info->CurrentFontWnd->OpenInfo->pszFileName)
290 {
291 Info->CurrentFontWnd->OpenInfo->pszFileName = (PWSTR) HeapAlloc(hProcessHeap, 0, MAX_PATH);
292 Info->CurrentFontWnd->OpenInfo->pszFileName[0] = 0;
293 }
294 else if(!Info->CurrentFontWnd->OpenInfo->bBinaryFileOpened)
295 {
296 // For a file in another format, the user has to enter a new file name as well
297 Info->CurrentFontWnd->OpenInfo->pszFileName[0] = 0;
298 }
299
300 if( !DoSaveFile(Info->CurrentFontWnd->OpenInfo->pszFileName) )
301 return;
302 }
303
304 // Save the binary font
305 hFile = CreateFileW(Info->CurrentFontWnd->OpenInfo->pszFileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
306
307 if(hFile == INVALID_HANDLE_VALUE)
308 {
309 LocalizedError( IDS_OPENERROR, GetLastError() );
310 return;
311 }
312
313 if( !WriteFile(hFile, Info->CurrentFontWnd->Font, sizeof(BITMAP_FONT), &dwBytesWritten, NULL) )
314 LocalizedError( IDS_WRITEERROR, GetLastError() );
315
316 CloseHandle(hFile);
317 }
318
319 static VOID
320 CopyCurrentGlyph(IN PFONT_WND_INFO FontWndInfo)
321 {
322 HGLOBAL hMem;
323 PUCHAR pCharacterBits;
324
325 if(!OpenClipboard(NULL))
326 return;
327
328 EmptyClipboard();
329
330 hMem = GlobalAlloc(GMEM_MOVEABLE, 8);
331 pCharacterBits = GlobalLock(hMem);
332 RtlCopyMemory(pCharacterBits, FontWndInfo->Font->Bits + FontWndInfo->uSelectedCharacter * 8, 8);
333 GlobalUnlock(hMem);
334
335 SetClipboardData(uCharacterClipboardFormat, hMem);
336
337 CloseClipboard();
338 }
339
340 static VOID
341 PasteIntoCurrentGlyph(IN PFONT_WND_INFO FontWndInfo)
342 {
343 HGLOBAL hMem;
344
345 if(!IsClipboardFormatAvailable(uCharacterClipboardFormat))
346 return;
347
348 if(!OpenClipboard(NULL))
349 return;
350
351 hMem = GetClipboardData(uCharacterClipboardFormat);
352 if(hMem)
353 {
354 PUCHAR pCharacterBits;
355
356 pCharacterBits = GlobalLock(hMem);
357 if(pCharacterBits)
358 {
359 RECT CharacterRect;
360 UINT uFontRow;
361 UINT uFontColumn;
362
363 RtlCopyMemory(FontWndInfo->Font->Bits + FontWndInfo->uSelectedCharacter * 8, pCharacterBits, 8);
364 GlobalUnlock(hMem);
365
366 FontWndInfo->OpenInfo->bModified = TRUE;
367
368 GetCharacterPosition(FontWndInfo->uSelectedCharacter, &uFontRow, &uFontColumn);
369 GetCharacterRect(uFontRow, uFontColumn, &CharacterRect);
370 InvalidateRect(FontWndInfo->hFontBoxesWnd, &CharacterRect, FALSE);
371 }
372 }
373
374 CloseClipboard();
375 }
376
377 VOID
378 SetPasteButtonState(IN PMAIN_WND_INFO Info)
379 {
380 SetToolbarButtonState(Info,
381 ID_EDIT_PASTE,
382 (Info->CurrentFontWnd && IsClipboardFormatAvailable(uCharacterClipboardFormat)));
383 }
384
385 static BOOL
386 MenuCommand(IN INT nMenuItemID, IN PMAIN_WND_INFO Info)
387 {
388 switch(nMenuItemID)
389 {
390 // File Menu
391 case ID_FILE_NEW:
392 DoFileNew(Info);
393 return TRUE;
394
395 case ID_FILE_OPEN:
396 DoFileOpen(Info);
397 return TRUE;
398
399 case ID_FILE_CLOSE:
400 SendMessageW(Info->CurrentFontWnd->hSelf, WM_CLOSE, 0, 0);
401 return TRUE;
402
403 case ID_FILE_SAVE:
404 DoFileSave(Info, FALSE);
405 return TRUE;
406
407 case ID_FILE_SAVE_AS:
408 DoFileSave(Info, TRUE);
409 return TRUE;
410
411 case ID_FILE_EXIT:
412 PostMessage(Info->hMainWnd, WM_CLOSE, 0, 0);
413 return TRUE;
414
415 // Edit Menu
416 case ID_EDIT_GLYPH:
417 EditCurrentGlyph(Info->CurrentFontWnd);
418 return TRUE;
419
420 case ID_EDIT_COPY:
421 CopyCurrentGlyph(Info->CurrentFontWnd);
422 return TRUE;
423
424 case ID_EDIT_PASTE:
425 PasteIntoCurrentGlyph(Info->CurrentFontWnd);
426 return TRUE;
427
428 // Window Menu
429 case ID_WINDOW_TILE_HORZ:
430 SendMessageW(Info->hMdiClient, WM_MDITILE, MDITILE_HORIZONTAL, 0);
431 return TRUE;
432
433 case ID_WINDOW_TILE_VERT:
434 SendMessageW(Info->hMdiClient, WM_MDITILE, MDITILE_VERTICAL, 0);
435 return TRUE;
436
437 case ID_WINDOW_CASCADE:
438 SendMessageW(Info->hMdiClient, WM_MDICASCADE, 0, 0);
439 return TRUE;
440
441 case ID_WINDOW_ARRANGE:
442 SendMessageW(Info->hMdiClient, WM_MDIICONARRANGE, 0, 0);
443 return TRUE;
444
445 case ID_WINDOW_NEXT:
446 SendMessageW(Info->hMdiClient, WM_MDINEXT, 0, 0);
447 return TRUE;
448
449 // Help Menu
450 case ID_HELP_ABOUT:
451 DialogBoxW( hInstance, MAKEINTRESOURCEW(IDD_ABOUT), Info->hMainWnd, AboutDlgProc );
452 return TRUE;
453 }
454
455 return FALSE;
456 }
457
458 static VOID
459 MainWndSize(PMAIN_WND_INFO Info, INT cx, INT cy)
460 {
461 HDWP dwp;
462 INT iMdiTop;
463 RECT ToolbarRect;
464
465 iMdiTop = 0;
466
467 dwp = BeginDeferWindowPos(2);
468 if(!dwp)
469 return;
470
471 if(Info->hToolbar)
472 {
473 GetWindowRect(Info->hToolbar, &ToolbarRect);
474 iMdiTop += ToolbarRect.bottom - ToolbarRect.top;
475
476 dwp = DeferWindowPos(dwp, Info->hToolbar, NULL, 0, 0, cx, ToolbarRect.bottom - ToolbarRect.top, SWP_NOZORDER);
477 if(!dwp)
478 return;
479 }
480
481 if(Info->hMdiClient)
482 {
483 dwp = DeferWindowPos(dwp, Info->hMdiClient, NULL, 0, iMdiTop, cx, cy - iMdiTop, SWP_NOZORDER);
484 if(!dwp)
485 return;
486 }
487
488 EndDeferWindowPos(dwp);
489 }
490
491 static LRESULT CALLBACK
492 MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
493 {
494 static HWND hNextClipboardViewer;
495 INT i;
496 PMAIN_WND_INFO Info;
497
498 Info = (PMAIN_WND_INFO) GetWindowLongPtrW(hwnd, GWLP_USERDATA);
499
500 if(Info || uMsg == WM_CREATE)
501 {
502 switch(uMsg)
503 {
504 case WM_COMMAND:
505 if( MenuCommand( LOWORD(wParam), Info ) )
506 return 0;
507
508 break;
509
510 case WM_CHANGECBCHAIN:
511 if((HWND)wParam == hNextClipboardViewer)
512 hNextClipboardViewer = (HWND)lParam;
513 else
514 SendMessage(hNextClipboardViewer, uMsg, wParam, lParam);
515
516 return 0;
517
518 case WM_CLOSE:
519 if(Info->FirstFontWnd)
520 {
521 // Send WM_CLOSE to all subwindows, so they can prompt for saving unsaved files
522 PFONT_WND_INFO pNextWnd;
523 PFONT_WND_INFO pWnd;
524
525 pWnd = Info->FirstFontWnd;
526
527 do
528 {
529 // The pWnd structure might already be destroyed after the WM_CLOSE, so we have to preserve the address of the next window here
530 pNextWnd = pWnd->NextFontWnd;
531
532 // Send WM_USER_APPCLOSE, so we can check for a custom return value
533 // In this case, we check if the user clicked the "Cancel" button in one of the prompts and if so, we don't close the app
534 if( !SendMessage(pWnd->hSelf, WM_USER_APPCLOSE, 0, 0) )
535 return 0;
536 }
537 while( (pWnd = pNextWnd) );
538 }
539 break;
540
541 case WM_CREATE:
542 Info = (PMAIN_WND_INFO)( ( (LPCREATESTRUCT)lParam )->lpCreateParams );
543 Info->hMainWnd = hwnd;
544 Info->hMenu = GetMenu(hwnd);
545 SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR)Info);
546
547 hNextClipboardViewer = SetClipboardViewer(hwnd);
548
549 InitMainWnd(Info);
550 InitResources(Info);
551
552 ShowWindow(hwnd, Info->nCmdShow);
553
554 for (i = 1; i < __argc; ++i)
555 {
556 MainWndOpenFile(Info, __wargv[i]);
557 }
558 DragAcceptFiles(hwnd, TRUE);
559 return 0;
560
561 case WM_DESTROY:
562 UnInitResources(Info);
563
564 HeapFree(hProcessHeap, 0, Info);
565 SetWindowLongPtrW(hwnd, GWLP_USERDATA, 0);
566 PostQuitMessage(0);
567 return 0;
568
569 case WM_DRAWCLIPBOARD:
570 SetPasteButtonState(Info);
571
572 // Pass the message to the next clipboard window in the chain
573 SendMessage(hNextClipboardViewer, uMsg, wParam, lParam);
574 return 0;
575
576 case WM_INITMENUPOPUP:
577 InitMenuPopup(Info);
578 break;
579
580 case WM_SIZE:
581 MainWndSize( Info, LOWORD(lParam), HIWORD(lParam) );
582 return 0;
583
584 case WM_DROPFILES:
585 MainWndDropFiles(Info, (HDROP)wParam);
586 return 0;
587 }
588 }
589
590 if(Info && Info->hMdiClient)
591 return DefFrameProcW(hwnd, Info->hMdiClient, uMsg, wParam, lParam);
592 else
593 return DefWindowProcW(hwnd, uMsg, wParam, lParam);
594 }
595
596 BOOL
597 CreateMainWindow(IN INT nCmdShow, OUT PMAIN_WND_INFO* Info)
598 {
599 HWND hMainWnd;
600
601 *Info = (PMAIN_WND_INFO) HeapAlloc( hProcessHeap, HEAP_ZERO_MEMORY, sizeof(MAIN_WND_INFO) );
602
603 if(*Info)
604 {
605 (*Info)->nCmdShow = nCmdShow;
606
607 hMainWnd = CreateWindowExW(0,
608 szMainWndClass,
609 szAppName,
610 WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
611 CW_USEDEFAULT,
612 CW_USEDEFAULT,
613 CW_USEDEFAULT,
614 CW_USEDEFAULT,
615 NULL,
616 LoadMenuW(hInstance, MAKEINTRESOURCEW(IDM_MAINMENU)),
617 hInstance,
618 *Info);
619
620 if(hMainWnd)
621 return TRUE;
622 else
623 HeapFree(hProcessHeap, 0, *Info);
624 }
625
626 return FALSE;
627 }
628
629 BOOL
630 InitMainWndClass(VOID)
631 {
632 WNDCLASSW wc = {0,};
633
634 wc.lpfnWndProc = MainWndProc;
635 wc.hInstance = hInstance;
636 wc.hCursor = LoadCursor( NULL, IDC_ARROW );
637 wc.hIcon = LoadIconW( hInstance, MAKEINTRESOURCEW(IDI_MAIN) );
638 wc.hbrBackground = (HBRUSH)( COLOR_BTNFACE + 1 );
639 wc.lpszClassName = szMainWndClass;
640
641 return RegisterClassW(&wc) != 0;
642 }
643
644 VOID
645 UnInitMainWndClass(VOID)
646 {
647 UnregisterClassW(szMainWndClass, hInstance);
648 }