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 OutOfMemory(IN PMAIN_WND_INFO Info) 200 { 201 MessageBoxW(Info->hMainWnd, L"Out of memory!", NULL, MB_ICONERROR); 202 } 203 204 static PFONT_OPEN_INFO 205 CreateOpenInfo(IN PMAIN_WND_INFO Info, BOOL bCreateNew, LPCWSTR File) 206 { 207 PFONT_OPEN_INFO OpenInfo; 208 209 OpenInfo = HeapAlloc(hProcessHeap, HEAP_ZERO_MEMORY, sizeof(FONT_OPEN_INFO)); 210 if (!OpenInfo) 211 { 212 OutOfMemory(Info); 213 return NULL; 214 } 215 216 OpenInfo->bCreateNew = bCreateNew; 217 OpenInfo->pszFileName = HeapAlloc(hProcessHeap, 0, MAX_PATH); 218 if (!OpenInfo->pszFileName) 219 { 220 OutOfMemory(Info); 221 HeapFree(hProcessHeap, 0, OpenInfo); 222 return NULL; 223 } 224 225 if (StringCchCopyW(OpenInfo->pszFileName, MAX_PATH, File) != S_OK) 226 { 227 MessageBoxW(Info->hMainWnd, L"Pathname is too long!", NULL, MB_ICONERROR); 228 HeapFree(hProcessHeap, 0, OpenInfo->pszFileName); 229 HeapFree(hProcessHeap, 0, OpenInfo); 230 return NULL; 231 } 232 233 return OpenInfo; 234 } 235 236 static VOID 237 DoFileNew(IN PMAIN_WND_INFO Info) 238 { 239 PFONT_OPEN_INFO OpenInfo = CreateOpenInfo(Info, TRUE, L""); 240 if (!OpenInfo) 241 return; 242 243 CreateFontWindow(Info, OpenInfo); 244 } 245 246 static VOID 247 DoFileOpen(IN PMAIN_WND_INFO Info) 248 { 249 PFONT_OPEN_INFO OpenInfo = CreateOpenInfo(Info, FALSE, L""); 250 if (!OpenInfo) 251 return; 252 253 if (DoOpenFile(OpenInfo->pszFileName)) 254 { 255 CreateFontWindow(Info, OpenInfo); 256 return; 257 } 258 259 HeapFree(hProcessHeap, 0, OpenInfo->pszFileName); 260 HeapFree(hProcessHeap, 0, OpenInfo); 261 } 262 263 static VOID 264 MainWndOpenFile(IN PMAIN_WND_INFO Info, LPCWSTR File) 265 { 266 PFONT_OPEN_INFO OpenInfo = CreateOpenInfo(Info, FALSE, File); 267 if (!OpenInfo) 268 return; 269 270 CreateFontWindow(Info, OpenInfo); 271 } 272 273 static VOID 274 MainWndDropFiles(IN PMAIN_WND_INFO Info, HDROP hDrop) 275 { 276 WCHAR Path[MAX_PATH]; 277 INT i, Count = DragQueryFileW(hDrop, 0xFFFFFFFF, NULL, 0); 278 279 for (i = 0; i < Count; ++i) 280 { 281 DragQueryFileW(hDrop, i, Path, MAX_PATH); 282 MainWndOpenFile(Info, Path); 283 } 284 285 DragFinish(hDrop); 286 } 287 288 VOID 289 DoFileSave(IN PMAIN_WND_INFO Info, IN BOOL bSaveAs) 290 { 291 DWORD dwBytesWritten; 292 HANDLE hFile; 293 294 // Show the "Save" dialog 295 // - if "Save As" was clicked 296 // - if the file was not yet saved 297 // - if another format than the binary format was opened 298 if(bSaveAs || !Info->CurrentFontWnd->OpenInfo->bBinaryFileOpened) 299 { 300 if(!Info->CurrentFontWnd->OpenInfo->pszFileName) 301 { 302 Info->CurrentFontWnd->OpenInfo->pszFileName = (PWSTR) HeapAlloc(hProcessHeap, 0, MAX_PATH); 303 Info->CurrentFontWnd->OpenInfo->pszFileName[0] = 0; 304 } 305 else if(!Info->CurrentFontWnd->OpenInfo->bBinaryFileOpened) 306 { 307 // For a file in another format, the user has to enter a new file name as well 308 Info->CurrentFontWnd->OpenInfo->pszFileName[0] = 0; 309 } 310 311 if( !DoSaveFile(Info->CurrentFontWnd->OpenInfo->pszFileName) ) 312 return; 313 } 314 315 // Save the binary font 316 hFile = CreateFileW(Info->CurrentFontWnd->OpenInfo->pszFileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 317 318 if(hFile == INVALID_HANDLE_VALUE) 319 { 320 LocalizedError( IDS_OPENERROR, GetLastError() ); 321 return; 322 } 323 324 if( !WriteFile(hFile, Info->CurrentFontWnd->Font, sizeof(BITMAP_FONT), &dwBytesWritten, NULL) ) 325 LocalizedError( IDS_WRITEERROR, GetLastError() ); 326 327 CloseHandle(hFile); 328 } 329 330 static VOID 331 CopyCurrentGlyph(IN PFONT_WND_INFO FontWndInfo) 332 { 333 HGLOBAL hMem; 334 PUCHAR pCharacterBits; 335 336 if(!OpenClipboard(NULL)) 337 return; 338 339 EmptyClipboard(); 340 341 hMem = GlobalAlloc(GMEM_MOVEABLE, 8); 342 pCharacterBits = GlobalLock(hMem); 343 RtlCopyMemory(pCharacterBits, FontWndInfo->Font->Bits + FontWndInfo->uSelectedCharacter * 8, 8); 344 GlobalUnlock(hMem); 345 346 SetClipboardData(uCharacterClipboardFormat, hMem); 347 348 CloseClipboard(); 349 } 350 351 static VOID 352 PasteIntoCurrentGlyph(IN PFONT_WND_INFO FontWndInfo) 353 { 354 HGLOBAL hMem; 355 356 if(!IsClipboardFormatAvailable(uCharacterClipboardFormat)) 357 return; 358 359 if(!OpenClipboard(NULL)) 360 return; 361 362 hMem = GetClipboardData(uCharacterClipboardFormat); 363 if(hMem) 364 { 365 PUCHAR pCharacterBits; 366 367 pCharacterBits = GlobalLock(hMem); 368 if(pCharacterBits) 369 { 370 RECT CharacterRect; 371 UINT uFontRow; 372 UINT uFontColumn; 373 374 RtlCopyMemory(FontWndInfo->Font->Bits + FontWndInfo->uSelectedCharacter * 8, pCharacterBits, 8); 375 GlobalUnlock(hMem); 376 377 FontWndInfo->OpenInfo->bModified = TRUE; 378 379 GetCharacterPosition(FontWndInfo->uSelectedCharacter, &uFontRow, &uFontColumn); 380 GetCharacterRect(uFontRow, uFontColumn, &CharacterRect); 381 InvalidateRect(FontWndInfo->hFontBoxesWnd, &CharacterRect, FALSE); 382 } 383 } 384 385 CloseClipboard(); 386 } 387 388 VOID 389 SetPasteButtonState(IN PMAIN_WND_INFO Info) 390 { 391 SetToolbarButtonState(Info, 392 ID_EDIT_PASTE, 393 (Info->CurrentFontWnd && IsClipboardFormatAvailable(uCharacterClipboardFormat))); 394 } 395 396 static BOOL 397 MenuCommand(IN INT nMenuItemID, IN PMAIN_WND_INFO Info) 398 { 399 switch(nMenuItemID) 400 { 401 // File Menu 402 case ID_FILE_NEW: 403 DoFileNew(Info); 404 return TRUE; 405 406 case ID_FILE_OPEN: 407 DoFileOpen(Info); 408 return TRUE; 409 410 case ID_FILE_CLOSE: 411 SendMessageW(Info->CurrentFontWnd->hSelf, WM_CLOSE, 0, 0); 412 return TRUE; 413 414 case ID_FILE_SAVE: 415 DoFileSave(Info, FALSE); 416 return TRUE; 417 418 case ID_FILE_SAVE_AS: 419 DoFileSave(Info, TRUE); 420 return TRUE; 421 422 case ID_FILE_EXIT: 423 PostMessage(Info->hMainWnd, WM_CLOSE, 0, 0); 424 return TRUE; 425 426 // Edit Menu 427 case ID_EDIT_GLYPH: 428 EditCurrentGlyph(Info->CurrentFontWnd); 429 return TRUE; 430 431 case ID_EDIT_COPY: 432 CopyCurrentGlyph(Info->CurrentFontWnd); 433 return TRUE; 434 435 case ID_EDIT_PASTE: 436 PasteIntoCurrentGlyph(Info->CurrentFontWnd); 437 return TRUE; 438 439 // Window Menu 440 case ID_WINDOW_TILE_HORZ: 441 SendMessageW(Info->hMdiClient, WM_MDITILE, MDITILE_HORIZONTAL, 0); 442 return TRUE; 443 444 case ID_WINDOW_TILE_VERT: 445 SendMessageW(Info->hMdiClient, WM_MDITILE, MDITILE_VERTICAL, 0); 446 return TRUE; 447 448 case ID_WINDOW_CASCADE: 449 SendMessageW(Info->hMdiClient, WM_MDICASCADE, 0, 0); 450 return TRUE; 451 452 case ID_WINDOW_ARRANGE: 453 SendMessageW(Info->hMdiClient, WM_MDIICONARRANGE, 0, 0); 454 return TRUE; 455 456 case ID_WINDOW_NEXT: 457 SendMessageW(Info->hMdiClient, WM_MDINEXT, 0, 0); 458 return TRUE; 459 460 // Help Menu 461 case ID_HELP_ABOUT: 462 DialogBoxW( hInstance, MAKEINTRESOURCEW(IDD_ABOUT), Info->hMainWnd, AboutDlgProc ); 463 return TRUE; 464 } 465 466 return FALSE; 467 } 468 469 static VOID 470 MainWndSize(PMAIN_WND_INFO Info, INT cx, INT cy) 471 { 472 HDWP dwp; 473 INT iMdiTop; 474 RECT ToolbarRect; 475 476 iMdiTop = 0; 477 478 dwp = BeginDeferWindowPos(2); 479 if(!dwp) 480 return; 481 482 if(Info->hToolbar) 483 { 484 GetWindowRect(Info->hToolbar, &ToolbarRect); 485 iMdiTop += ToolbarRect.bottom - ToolbarRect.top; 486 487 dwp = DeferWindowPos(dwp, Info->hToolbar, NULL, 0, 0, cx, ToolbarRect.bottom - ToolbarRect.top, SWP_NOZORDER); 488 if(!dwp) 489 return; 490 } 491 492 if(Info->hMdiClient) 493 { 494 dwp = DeferWindowPos(dwp, Info->hMdiClient, NULL, 0, iMdiTop, cx, cy - iMdiTop, SWP_NOZORDER); 495 if(!dwp) 496 return; 497 } 498 499 EndDeferWindowPos(dwp); 500 } 501 502 static LRESULT CALLBACK 503 MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 504 { 505 static HWND hNextClipboardViewer; 506 INT i; 507 PMAIN_WND_INFO Info; 508 509 Info = (PMAIN_WND_INFO) GetWindowLongPtrW(hwnd, GWLP_USERDATA); 510 511 if(Info || uMsg == WM_CREATE) 512 { 513 switch(uMsg) 514 { 515 case WM_COMMAND: 516 if( MenuCommand( LOWORD(wParam), Info ) ) 517 return 0; 518 519 break; 520 521 case WM_CHANGECBCHAIN: 522 if((HWND)wParam == hNextClipboardViewer) 523 hNextClipboardViewer = (HWND)lParam; 524 else 525 SendMessage(hNextClipboardViewer, uMsg, wParam, lParam); 526 527 return 0; 528 529 case WM_CLOSE: 530 if(Info->FirstFontWnd) 531 { 532 // Send WM_CLOSE to all subwindows, so they can prompt for saving unsaved files 533 PFONT_WND_INFO pNextWnd; 534 PFONT_WND_INFO pWnd; 535 536 pWnd = Info->FirstFontWnd; 537 538 do 539 { 540 // The pWnd structure might already be destroyed after the WM_CLOSE, so we have to preserve the address of the next window here 541 pNextWnd = pWnd->NextFontWnd; 542 543 // Send WM_USER_APPCLOSE, so we can check for a custom return value 544 // 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 545 if( !SendMessage(pWnd->hSelf, WM_USER_APPCLOSE, 0, 0) ) 546 return 0; 547 } 548 while( (pWnd = pNextWnd) ); 549 } 550 break; 551 552 case WM_CREATE: 553 Info = (PMAIN_WND_INFO)( ( (LPCREATESTRUCT)lParam )->lpCreateParams ); 554 Info->hMainWnd = hwnd; 555 Info->hMenu = GetMenu(hwnd); 556 SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR)Info); 557 558 hNextClipboardViewer = SetClipboardViewer(hwnd); 559 560 InitMainWnd(Info); 561 InitResources(Info); 562 563 ShowWindow(hwnd, Info->nCmdShow); 564 565 for (i = 1; i < __argc; ++i) 566 { 567 MainWndOpenFile(Info, __wargv[i]); 568 } 569 DragAcceptFiles(hwnd, TRUE); 570 return 0; 571 572 case WM_DESTROY: 573 UnInitResources(Info); 574 575 HeapFree(hProcessHeap, 0, Info); 576 SetWindowLongPtrW(hwnd, GWLP_USERDATA, 0); 577 PostQuitMessage(0); 578 return 0; 579 580 case WM_DRAWCLIPBOARD: 581 SetPasteButtonState(Info); 582 583 // Pass the message to the next clipboard window in the chain 584 SendMessage(hNextClipboardViewer, uMsg, wParam, lParam); 585 return 0; 586 587 case WM_INITMENUPOPUP: 588 InitMenuPopup(Info); 589 break; 590 591 case WM_SIZE: 592 MainWndSize( Info, LOWORD(lParam), HIWORD(lParam) ); 593 return 0; 594 595 case WM_DROPFILES: 596 MainWndDropFiles(Info, (HDROP)wParam); 597 return 0; 598 } 599 } 600 601 if(Info && Info->hMdiClient) 602 return DefFrameProcW(hwnd, Info->hMdiClient, uMsg, wParam, lParam); 603 else 604 return DefWindowProcW(hwnd, uMsg, wParam, lParam); 605 } 606 607 BOOL 608 CreateMainWindow(IN INT nCmdShow, OUT PMAIN_WND_INFO* Info) 609 { 610 HWND hMainWnd; 611 612 *Info = (PMAIN_WND_INFO) HeapAlloc( hProcessHeap, HEAP_ZERO_MEMORY, sizeof(MAIN_WND_INFO) ); 613 614 if(*Info) 615 { 616 (*Info)->nCmdShow = nCmdShow; 617 618 hMainWnd = CreateWindowExW(0, 619 szMainWndClass, 620 szAppName, 621 WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 622 CW_USEDEFAULT, 623 CW_USEDEFAULT, 624 CW_USEDEFAULT, 625 CW_USEDEFAULT, 626 NULL, 627 LoadMenuW(hInstance, MAKEINTRESOURCEW(IDM_MAINMENU)), 628 hInstance, 629 *Info); 630 631 if(hMainWnd) 632 return TRUE; 633 else 634 HeapFree(hProcessHeap, 0, *Info); 635 } 636 637 return FALSE; 638 } 639 640 BOOL 641 InitMainWndClass(VOID) 642 { 643 WNDCLASSW wc = {0,}; 644 645 wc.lpfnWndProc = MainWndProc; 646 wc.hInstance = hInstance; 647 wc.hCursor = LoadCursor( NULL, IDC_ARROW ); 648 wc.hIcon = LoadIconW( hInstance, MAKEINTRESOURCEW(IDI_MAIN) ); 649 wc.hbrBackground = (HBRUSH)( COLOR_BTNFACE + 1 ); 650 wc.lpszClassName = szMainWndClass; 651 652 return RegisterClassW(&wc) != 0; 653 } 654 655 VOID 656 UnInitMainWndClass(VOID) 657 { 658 UnregisterClassW(szMainWndClass, hInstance); 659 } 660