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>
20 /* Font-enumeration callback */
24 EnumFontNames(ENUMLOGFONTEXW
*lpelfe
,
25 NEWTEXTMETRICEXW
*lpntme
,
29 HWND hwndCombo
= (HWND
)lParam
;
30 LPWSTR pszName
= lpelfe
->elfLogFont
.lfFaceName
;
32 /* make sure font doesn't already exist in our list */
33 if(SendMessageW(hwndCombo
,
36 (LPARAM
)pszName
) == CB_ERR
)
43 idx
= (INT
)SendMessageW(hwndCombo
,
48 /* record the font's attributes (Fixedwidth and Truetype) */
49 fFixed
= (lpelfe
->elfLogFont
.lfPitchAndFamily
& FIXED_PITCH
) ? TRUE
: FALSE
;
50 fTrueType
= (lpelfe
->elfLogFont
.lfOutPrecision
== OUT_STROKE_PRECIS
) ? TRUE
: FALSE
;
52 /* store this information in the list-item's userdata area */
53 SendMessageW(hwndCombo
,
56 MAKEWPARAM(fFixed
, fTrueType
));
63 /* Initialize the font-list by enumeration all system fonts */
66 FillFontStyleComboList(HWND hwndCombo
)
71 /* FIXME: for fun, draw each font in its own style */
72 HFONT hFont
= GetStockObject(DEFAULT_GUI_FONT
);
73 SendMessageW(hwndCombo
,
78 ZeroMemory(&lf
, sizeof(lf
));
79 lf
.lfCharSet
= DEFAULT_CHARSET
;
81 hdc
= GetDC(hwndCombo
);
83 /* store the list of fonts in the combo */
84 EnumFontFamiliesExW(hdc
,
86 (FONTENUMPROCW
)EnumFontNames
,
93 SendMessageW(hwndCombo
,
102 ChangeMapFont(HWND hDlg
)
109 hCombo
= GetDlgItem(hDlg
, IDC_FONTCOMBO
);
111 Len
= GetWindowTextLengthW(hCombo
);
115 lpFontName
= HeapAlloc(GetProcessHeap(),
117 (Len
+ 1) * sizeof(WCHAR
));
126 hMap
= GetDlgItem(hDlg
, IDC_FONTMAP
);
134 HeapFree(GetProcessHeap(),
140 // Copy collected characters into the clipboard
143 CopyCharacters(HWND hDlg
)
145 HWND hText
= GetDlgItem(hDlg
, IDC_TEXTBOX
);
146 DWORD dwStart
, dwEnd
;
148 // Acquire selection limits
149 SendMessage(hText
, EM_GETSEL
, (WPARAM
)&dwStart
, (LPARAM
)&dwEnd
);
151 // Test if the whose text is unselected
152 if(dwStart
== dwEnd
) {
154 // Select the whole text
155 SendMessageW(hText
, EM_SETSEL
, 0, -1);
158 SendMessageW(hText
, WM_COPY
, 0, 0);
160 // Restore previous values
161 SendMessageW(hText
, EM_SETSEL
, (WPARAM
)dwStart
, (LPARAM
)dwEnd
);
166 SendMessageW(hText
, WM_COPY
, 0, 0);
170 // Recover charset for the given font
173 GetFontMetrics(HWND hWnd
, HFONT hFont
)
180 hOldObj
= SelectObject(hDC
, hFont
);
181 GetTextMetrics(hDC
, &tmFont
);
182 SelectObject(hDC
, hOldObj
);
183 ReleaseDC(hWnd
, hDC
);
185 return tmFont
.tmCharSet
;
188 // Select a new character
191 AddCharToSelection(HWND hDlg
, WCHAR ch
)
193 HWND hMap
= GetDlgItem(hDlg
, IDC_FONTMAP
);
194 HWND hText
= GetDlgItem(hDlg
, IDC_TEXTBOX
);
199 // Retrieve current character selected
202 ch
= (WCHAR
) SendMessageW(hMap
, FM_GETCHAR
, 0, 0);
207 // Retrieve current selected font
208 hFont
= (HFONT
)SendMessage(hMap
, FM_GETHFONT
, 0, 0);
210 // Recover LOGFONT structure from hFont
211 if (!GetObject(hFont
, sizeof(LOGFONT
), &lFont
))
214 // Recover font properties of Richedit control
215 ZeroMemory(&cf
, sizeof(cf
));
216 cf
.cbSize
= sizeof(cf
);
217 SendMessage(hText
, EM_GETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&cf
);
219 // Apply properties of the new font
220 cf
.bCharSet
= GetFontMetrics(hText
, hFont
);
223 wcscpy(cf
.szFaceName
, lFont
.lfFaceName
);
225 // Update font properties
226 SendMessage(hText
, EM_SETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&cf
);
228 // Send selected character to Richedit
229 SendMessage(hText
, WM_CHAR
, (WPARAM
)ch
, 0);
235 UpdateSettings(HWND hDlg
)
237 if (hDlg
== hCharmapDlg
)
239 Settings
.IsAdvancedView
=
240 SendDlgItemMessage(hDlg
, IDC_CHECK_ADVANCED
, BM_GETCHECK
, 0, 0);
243 if (hDlg
== hAdvancedDlg
)
250 ChangeView(HWND hWnd
)
260 UINT DeskTopWidth
, DeskTopHeight
;
262 GetClientRect(hCharmapDlg
, &rcCharmap
);
263 GetClientRect(hAdvancedDlg
, &rcAdvanced
);
264 GetWindowRect(hWnd
, &rcPanelExt
);
265 GetClientRect(hWnd
, &rcPanelInt
);
266 GetClientRect(hStatusWnd
, &rcStatus
);
268 DeskTopWidth
= GetSystemMetrics(SM_CXFULLSCREEN
);
269 DeskTopHeight
= GetSystemMetrics(SM_CYFULLSCREEN
);
271 DeX
= (rcPanelExt
.right
- rcPanelExt
.left
) - rcPanelInt
.right
;
272 DeY
= (rcPanelExt
.bottom
- rcPanelExt
.top
) - rcPanelInt
.bottom
;
274 MoveWindow(hCharmapDlg
, 0, 0, rcCharmap
.right
, rcCharmap
.bottom
, FALSE
);
275 MoveWindow(hAdvancedDlg
, 0, rcCharmap
.bottom
, rcAdvanced
.right
, rcAdvanced
.bottom
, FALSE
);
277 ShowWindow(hAdvancedDlg
, (Settings
.IsAdvancedView
) ? SW_SHOW
: SW_HIDE
);
279 xPos
= rcPanelExt
.left
;
280 yPos
= rcPanelExt
.top
;
282 Width
= DeX
+ rcCharmap
.right
;
283 Height
= DeY
+ rcCharmap
.bottom
+ rcStatus
.bottom
;
285 if (Settings
.IsAdvancedView
)
286 Height
+= rcAdvanced
.bottom
;
288 if ((xPos
+ Width
) > DeskTopWidth
)
289 xPos
+= DeskTopWidth
- (xPos
+ Width
);
291 if ((yPos
+ Height
) > DeskTopHeight
)
292 yPos
+= DeskTopHeight
- (yPos
+ Height
);
303 CharMapDlgProc(HWND hDlg
,
314 FillFontStyleComboList(GetDlgItem(hDlg
,
319 // Configure Richedi control for sending notification changes.
320 evMask
= SendDlgItemMessage(hDlg
, IDC_TEXTBOX
, EM_GETEVENTMASK
, 0, 0);
321 evMask
|= ENM_CHANGE
;
322 SendDlgItemMessage(hDlg
, IDC_TEXTBOX
, EM_SETEVENTMASK
, 0, (LPARAM
)evMask
);
329 switch(LOWORD(wParam
))
332 switch (HIWORD(wParam
))
335 AddCharToSelection(hDlg
, LOWORD(lParam
));
341 if (HIWORD(wParam
) == CBN_SELCHANGE
)
348 AddCharToSelection(hDlg
, 0);
352 switch (HIWORD(wParam
)) {
354 if (GetWindowTextLength(GetDlgItem(hDlg
, IDC_TEXTBOX
)) == 0)
355 EnableWindow(GetDlgItem(hDlg
, IDC_COPY
), FALSE
);
357 EnableWindow(GetDlgItem(hDlg
, IDC_COPY
), TRUE
);
363 CopyCharacters(hDlg
);
366 case IDC_CHECK_ADVANCED
:
367 UpdateSettings(hDlg
);
368 ChangeView(GetParent(hDlg
));
384 AdvancedDlgProc(HWND hDlg
,
402 OnCreate(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
405 WCHAR lpAboutText
[256];
407 hCharmapDlg
= CreateDialog(hInstance
,
408 MAKEINTRESOURCE(IDD_CHARMAP
),
412 hAdvancedDlg
= CreateDialog(hInstance
,
413 MAKEINTRESOURCE(IDD_ADVANCED
),
417 hStatusWnd
= CreateWindow(STATUSCLASSNAME
,
419 WS_CHILD
| WS_VISIBLE
,
422 (HMENU
)IDD_STATUSBAR
,
426 // Set the status bar for multiple parts output
427 SendMessage(hStatusWnd
, SB_SIMPLE
, (WPARAM
)FALSE
, (LPARAM
)0);
431 hSysMenu
= GetSystemMenu(hWnd
, FALSE
);
433 if (hSysMenu
!= NULL
)
435 if (LoadStringW(hInstance
, IDS_ABOUT
, lpAboutText
, SIZEOF(lpAboutText
)))
437 AppendMenuW(hSysMenu
, MF_SEPARATOR
, 0, NULL
);
438 AppendMenuW(hSysMenu
, MF_STRING
, ID_ABOUT
, lpAboutText
);
445 static LRESULT CALLBACK
446 PanelWndProc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
450 return OnCreate(hWnd
, wParam
, lParam
);
457 SendMessage(hStatusWnd
, msg
, wParam
, lParam
);
475 return DefWindowProc(hWnd
, msg
, wParam
, lParam
);
479 InitInstance(HINSTANCE hInst
)
481 WCHAR szClass
[] = L
"CharMap";
486 LoadStringW(hInst
, IDS_TITLE
, szTitle
, SIZEOF(szTitle
));
488 hSmIcon
= LoadImage(hInstance
,
489 MAKEINTRESOURCE(IDI_ICON
),
495 hBgIcon
= LoadImage(hInstance
,
496 MAKEINTRESOURCE(IDI_ICON
),
503 ZeroMemory(&wc
, sizeof(wc
));
505 wc
.cbSize
= sizeof(wc
);
506 wc
.lpfnWndProc
= PanelWndProc
;
507 wc
.hInstance
= hInst
;
509 wc
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
510 wc
.hbrBackground
= (HBRUSH
)GetStockObject(NULL_BRUSH
);
511 wc
.lpszMenuName
= NULL
;
512 wc
.lpszClassName
= szClass
;
513 wc
.hIconSm
= hSmIcon
;
515 RegisterClassExW(&wc
);
517 hWnd
= CreateWindowW(
520 WS_CAPTION
| WS_SYSMENU
| WS_MINIMIZEBOX
,
533 ShowWindow(hWnd
, SW_SHOW
);
542 wWinMain(HINSTANCE hInst
,
547 INITCOMMONCONTROLSEX iccx
;
554 iccx
.dwSize
= sizeof(INITCOMMONCONTROLSEX
);
555 iccx
.dwICC
= ICC_TAB_CLASSES
;
556 InitCommonControlsEx(&iccx
);
558 if (RegisterMapClasses(hInstance
))
560 hRichEd20
= LoadLibraryW(L
"RICHED20.DLL");
562 if (hRichEd20
!= NULL
)
568 if (GetMessage(&Msg
, NULL
, 0, 0) <= 0)
574 TranslateMessage(&Msg
);
575 DispatchMessage(&Msg
);
578 FreeLibrary(hRichEd20
);
580 UnregisterMapClasses(hInstance
);