2 * PROJECT: ReactOS Character Map
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/charmap/charmap.c
5 * PURPOSE: main dialog implementation
6 * COPYRIGHT: Copyright 2007 Ged Murphy <gedmurphy@reactos.org>
16 #define REMOVE_ADVANCED
28 /* GetUName prototype */
29 typedef int (WINAPI
* GETUNAME
)(WORD wCharCode
, LPWSTR lpbuf
);
32 /* Font-enumeration callback */
36 EnumFontNames(ENUMLOGFONTEXW
*lpelfe
,
37 NEWTEXTMETRICEXW
*lpntme
,
41 HWND hwndCombo
= (HWND
)lParam
;
42 LPWSTR pszName
= lpelfe
->elfLogFont
.lfFaceName
;
44 /* Skip rotated font */
45 if(pszName
[0] == L
'@') return 1;
47 /* make sure font doesn't already exist in our list */
48 if(SendMessageW(hwndCombo
,
51 (LPARAM
)pszName
) == CB_ERR
)
58 idx
= (INT
)SendMessageW(hwndCombo
,
63 /* record the font's attributes (Fixedwidth and Truetype) */
64 fFixed
= (lpelfe
->elfLogFont
.lfPitchAndFamily
& FIXED_PITCH
) ? TRUE
: FALSE
;
65 fTrueType
= (lpelfe
->elfLogFont
.lfOutPrecision
== OUT_STROKE_PRECIS
) ? TRUE
: FALSE
;
67 /* store this information in the list-item's userdata area */
68 SendMessageW(hwndCombo
,
71 MAKEWPARAM(fFixed
, fTrueType
));
78 /* Initialize the font-list by enumeration all system fonts */
81 FillFontStyleComboList(HWND hwndCombo
)
86 /* FIXME: for fun, draw each font in its own style */
87 HFONT hFont
= GetStockObject(DEFAULT_GUI_FONT
);
88 SendMessageW(hwndCombo
,
93 ZeroMemory(&lf
, sizeof(lf
));
94 lf
.lfCharSet
= DEFAULT_CHARSET
;
96 hdc
= GetDC(hwndCombo
);
98 /* store the list of fonts in the combo */
99 EnumFontFamiliesExW(hdc
,
101 (FONTENUMPROCW
)EnumFontNames
,
108 SendMessageW(hwndCombo
,
117 ChangeMapFont(HWND hDlg
)
124 hCombo
= GetDlgItem(hDlg
, IDC_FONTCOMBO
);
126 Len
= GetWindowTextLengthW(hCombo
);
130 lpFontName
= HeapAlloc(GetProcessHeap(),
132 (Len
+ 1) * sizeof(WCHAR
));
141 hMap
= GetDlgItem(hDlg
, IDC_FONTMAP
);
149 HeapFree(GetProcessHeap(),
155 // Copy collected characters into the clipboard
158 CopyCharacters(HWND hDlg
)
160 HWND hText
= GetDlgItem(hDlg
, IDC_TEXTBOX
);
161 DWORD dwStart
, dwEnd
;
163 // Acquire selection limits
164 SendMessage(hText
, EM_GETSEL
, (WPARAM
)&dwStart
, (LPARAM
)&dwEnd
);
166 // Test if the whose text is unselected
167 if(dwStart
== dwEnd
) {
169 // Select the whole text
170 SendMessageW(hText
, EM_SETSEL
, 0, -1);
173 SendMessageW(hText
, WM_COPY
, 0, 0);
175 // Restore previous values
176 SendMessageW(hText
, EM_SETSEL
, (WPARAM
)dwStart
, (LPARAM
)dwEnd
);
181 SendMessageW(hText
, WM_COPY
, 0, 0);
185 // Recover charset for the given font
188 GetFontMetrics(HWND hWnd
, HFONT hFont
)
195 hOldObj
= SelectObject(hDC
, hFont
);
196 GetTextMetrics(hDC
, &tmFont
);
197 SelectObject(hDC
, hOldObj
);
198 ReleaseDC(hWnd
, hDC
);
200 return tmFont
.tmCharSet
;
203 // Select a new character
206 AddCharToSelection(HWND hDlg
, WCHAR ch
)
208 HWND hMap
= GetDlgItem(hDlg
, IDC_FONTMAP
);
209 HWND hText
= GetDlgItem(hDlg
, IDC_TEXTBOX
);
214 // Retrieve current character selected
217 ch
= (WCHAR
) SendMessageW(hMap
, FM_GETCHAR
, 0, 0);
222 // Retrieve current selected font
223 hFont
= (HFONT
)SendMessage(hMap
, FM_GETHFONT
, 0, 0);
225 // Recover LOGFONT structure from hFont
226 if (!GetObject(hFont
, sizeof(LOGFONT
), &lFont
))
229 // Recover font properties of Richedit control
230 ZeroMemory(&cf
, sizeof(cf
));
231 cf
.cbSize
= sizeof(cf
);
232 SendMessage(hText
, EM_GETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&cf
);
234 // Apply properties of the new font
235 cf
.bCharSet
= GetFontMetrics(hText
, hFont
);
238 wcscpy(cf
.szFaceName
, lFont
.lfFaceName
);
240 // Update font properties
241 SendMessage(hText
, EM_SETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&cf
);
243 // Send selected character to Richedit
244 SendMessage(hText
, WM_CHAR
, (WPARAM
)ch
, 0);
247 #ifndef REMOVE_ADVANCED
250 UpdateSettings(HWND hDlg
)
252 if (hDlg
== hCharmapDlg
)
254 Settings
.IsAdvancedView
=
255 SendDlgItemMessage(hDlg
, IDC_CHECK_ADVANCED
, BM_GETCHECK
, 0, 0);
259 if (hDlg
== hAdvancedDlg
)
266 UpdateStatusBar(WCHAR wch
)
268 WCHAR buff
[MAX_PATH
];
269 WCHAR szDesc
[MAX_PATH
];
273 GetUName(wch
, szDesc
);
274 wsprintfW(buff
, L
"U+%04X: %s", wch
, szDesc
);
275 SendMessageW(hStatusWnd
, SB_SETTEXT
, 0, (LPARAM
)buff
);
281 ChangeView(HWND hWnd
)
284 #ifndef REMOVE_ADVANCED
293 UINT DeskTopWidth
, DeskTopHeight
;
295 GetClientRect(hCharmapDlg
, &rcCharmap
);
296 #ifndef REMOVE_ADVANCED
297 GetClientRect(hAdvancedDlg
, &rcAdvanced
);
299 GetWindowRect(hWnd
, &rcPanelExt
);
300 GetClientRect(hWnd
, &rcPanelInt
);
301 GetClientRect(hStatusWnd
, &rcStatus
);
303 DeskTopWidth
= GetSystemMetrics(SM_CXFULLSCREEN
);
304 DeskTopHeight
= GetSystemMetrics(SM_CYFULLSCREEN
);
306 DeX
= (rcPanelExt
.right
- rcPanelExt
.left
) - rcPanelInt
.right
;
307 DeY
= (rcPanelExt
.bottom
- rcPanelExt
.top
) - rcPanelInt
.bottom
;
309 MoveWindow(hCharmapDlg
, 0, 0, rcCharmap
.right
, rcCharmap
.bottom
, FALSE
);
310 #ifndef REMOVE_ADVANCED
311 MoveWindow(hAdvancedDlg
, 0, rcCharmap
.bottom
, rcAdvanced
.right
, rcAdvanced
.bottom
, FALSE
);
312 ShowWindow(hAdvancedDlg
, (Settings
.IsAdvancedView
) ? SW_SHOW
: SW_HIDE
);
314 xPos
= rcPanelExt
.left
;
315 yPos
= rcPanelExt
.top
;
317 Width
= DeX
+ rcCharmap
.right
;
318 Height
= DeY
+ rcCharmap
.bottom
+ rcStatus
.bottom
;
319 #ifndef REMOVE_ADVANCED
320 if (Settings
.IsAdvancedView
)
321 Height
+= rcAdvanced
.bottom
;
323 if ((xPos
+ Width
) > DeskTopWidth
)
324 xPos
+= DeskTopWidth
- (xPos
+ Width
);
326 if ((yPos
+ Height
) > DeskTopHeight
)
327 yPos
+= DeskTopHeight
- (yPos
+ Height
);
338 CharMapDlgProc(HWND hDlg
,
348 #ifdef REMOVE_ADVANCED
352 FillFontStyleComboList(GetDlgItem(hDlg
,
357 // Configure Richedit control for sending notification changes.
358 evMask
= SendDlgItemMessage(hDlg
, IDC_TEXTBOX
, EM_GETEVENTMASK
, 0, 0);
359 evMask
|= ENM_CHANGE
;
360 SendDlgItemMessage(hDlg
, IDC_TEXTBOX
, EM_SETEVENTMASK
, 0, (LPARAM
)evMask
);
361 #ifdef REMOVE_ADVANCED
362 hAdv
= GetDlgItem(hDlg
, IDC_CHECK_ADVANCED
);
363 ShowWindow(hAdv
, SW_HIDE
);
370 switch(LOWORD(wParam
))
373 switch (HIWORD(wParam
))
376 AddCharToSelection(hDlg
, LOWORD(lParam
));
382 if (HIWORD(wParam
) == CBN_SELCHANGE
)
389 AddCharToSelection(hDlg
, 0);
393 switch (HIWORD(wParam
)) {
395 if (GetWindowTextLength(GetDlgItem(hDlg
, IDC_TEXTBOX
)) == 0)
396 EnableWindow(GetDlgItem(hDlg
, IDC_COPY
), FALSE
);
398 EnableWindow(GetDlgItem(hDlg
, IDC_COPY
), TRUE
);
404 CopyCharacters(hDlg
);
406 #ifndef REMOVE_ADVANCED
407 case IDC_CHECK_ADVANCED
:
408 UpdateSettings(hDlg
);
409 ChangeView(GetParent(hDlg
));
422 #ifndef REMOVE_ADVANCED
426 AdvancedDlgProc(HWND hDlg
,
445 PanelOnCreate(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
448 WCHAR lpAboutText
[256];
450 hCharmapDlg
= CreateDialog(hInstance
,
451 MAKEINTRESOURCE(IDD_CHARMAP
),
454 #ifndef REMOVE_ADVANCED
455 hAdvancedDlg
= CreateDialog(hInstance
,
456 MAKEINTRESOURCE(IDD_ADVANCED
),
460 hStatusWnd
= CreateWindow(STATUSCLASSNAME
,
462 WS_CHILD
| WS_VISIBLE
,
465 (HMENU
)IDD_STATUSBAR
,
469 // Set the status bar for multiple parts output
470 SendMessage(hStatusWnd
, SB_SIMPLE
, (WPARAM
)FALSE
, (LPARAM
)0);
474 hSysMenu
= GetSystemMenu(hWnd
, FALSE
);
476 if (hSysMenu
!= NULL
)
478 if (LoadStringW(hInstance
, IDS_ABOUT
, lpAboutText
, SIZEOF(lpAboutText
)))
480 AppendMenuW(hSysMenu
, MF_SEPARATOR
, 0, NULL
);
481 AppendMenuW(hSysMenu
, MF_STRING
, ID_ABOUT
, lpAboutText
);
488 static LRESULT CALLBACK
489 PanelWndProc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
493 // For now, the Help push button is disabled because of lacking of HTML Help support
494 EnableWindow(GetDlgItem(hWnd
, IDC_CMHELP
), FALSE
);
495 return PanelOnCreate(hWnd
, wParam
, lParam
);
502 SendMessage(hStatusWnd
, msg
, wParam
, lParam
);
520 return DefWindowProc(hWnd
, msg
, wParam
, lParam
);
524 InitInstance(HINSTANCE hInst
)
526 WCHAR szClass
[] = L
"CharMap";
531 LoadStringW(hInst
, IDS_TITLE
, szTitle
, SIZEOF(szTitle
));
533 hSmIcon
= LoadImage(hInstance
,
534 MAKEINTRESOURCE(IDI_ICON
),
540 hBgIcon
= LoadImage(hInstance
,
541 MAKEINTRESOURCE(IDI_ICON
),
548 ZeroMemory(&wc
, sizeof(wc
));
550 wc
.cbSize
= sizeof(wc
);
551 wc
.lpfnWndProc
= PanelWndProc
;
552 wc
.hInstance
= hInst
;
554 wc
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
555 wc
.hbrBackground
= (HBRUSH
)GetStockObject(NULL_BRUSH
);
556 wc
.lpszMenuName
= NULL
;
557 wc
.lpszClassName
= szClass
;
558 wc
.hIconSm
= hSmIcon
;
560 RegisterClassExW(&wc
);
562 hWnd
= CreateWindowW(
565 WS_CAPTION
| WS_SYSMENU
| WS_MINIMIZEBOX
,
578 ShowWindow(hWnd
, SW_SHOW
);
587 wWinMain(HINSTANCE hInst
,
592 INITCOMMONCONTROLSEX iccx
;
596 HINSTANCE hGetUName
= NULL
;
600 /* Mirroring code for the titlebar */
601 switch (GetUserDefaultUILanguage())
603 case MAKELANGID(LANG_HEBREW
, SUBLANG_DEFAULT
):
604 SetProcessDefaultLayout(LAYOUT_RTL
);
611 iccx
.dwSize
= sizeof(INITCOMMONCONTROLSEX
);
612 iccx
.dwICC
= ICC_TAB_CLASSES
;
613 InitCommonControlsEx(&iccx
);
615 /* Loading the GetUName function */
616 hGetUName
= LoadLibraryW(L
"getuname.dll");
617 if (hGetUName
!= NULL
)
619 GetUName
= (GETUNAME
) GetProcAddress(hGetUName
, "GetUName");
620 if (GetUName
== NULL
)
622 FreeLibrary(hGetUName
);
627 if (RegisterMapClasses(hInstance
))
629 hRichEd20
= LoadLibraryW(L
"RICHED20.DLL");
631 if (hRichEd20
!= NULL
)
637 if (GetMessage(&Msg
, NULL
, 0, 0) <= 0)
643 TranslateMessage(&Msg
);
644 DispatchMessage(&Msg
);
647 FreeLibrary(hRichEd20
);
649 UnregisterMapClasses(hInstance
);
652 if (hGetUName
!= NULL
)
653 FreeLibrary(hGetUName
);