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>
26 /* Font-enumeration callback */
30 EnumFontNames(ENUMLOGFONTEXW
*lpelfe
,
31 NEWTEXTMETRICEXW
*lpntme
,
35 HWND hwndCombo
= (HWND
)lParam
;
36 LPWSTR pszName
= lpelfe
->elfLogFont
.lfFaceName
;
38 /* make sure font doesn't already exist in our list */
39 if(SendMessageW(hwndCombo
,
42 (LPARAM
)pszName
) == CB_ERR
)
49 idx
= (INT
)SendMessageW(hwndCombo
,
54 /* record the font's attributes (Fixedwidth and Truetype) */
55 fFixed
= (lpelfe
->elfLogFont
.lfPitchAndFamily
& FIXED_PITCH
) ? TRUE
: FALSE
;
56 fTrueType
= (lpelfe
->elfLogFont
.lfOutPrecision
== OUT_STROKE_PRECIS
) ? TRUE
: FALSE
;
58 /* store this information in the list-item's userdata area */
59 SendMessageW(hwndCombo
,
62 MAKEWPARAM(fFixed
, fTrueType
));
69 /* Initialize the font-list by enumeration all system fonts */
72 FillFontStyleComboList(HWND hwndCombo
)
77 /* FIXME: for fun, draw each font in its own style */
78 HFONT hFont
= GetStockObject(DEFAULT_GUI_FONT
);
79 SendMessageW(hwndCombo
,
84 ZeroMemory(&lf
, sizeof(lf
));
85 lf
.lfCharSet
= DEFAULT_CHARSET
;
87 hdc
= GetDC(hwndCombo
);
89 /* store the list of fonts in the combo */
90 EnumFontFamiliesExW(hdc
,
92 (FONTENUMPROCW
)EnumFontNames
,
99 SendMessageW(hwndCombo
,
108 ChangeMapFont(HWND hDlg
)
115 hCombo
= GetDlgItem(hDlg
, IDC_FONTCOMBO
);
117 Len
= GetWindowTextLengthW(hCombo
);
121 lpFontName
= HeapAlloc(GetProcessHeap(),
123 (Len
+ 1) * sizeof(WCHAR
));
132 hMap
= GetDlgItem(hDlg
, IDC_FONTMAP
);
140 HeapFree(GetProcessHeap(),
146 // Copy collected characters into the clipboard
149 CopyCharacters(HWND hDlg
)
151 HWND hText
= GetDlgItem(hDlg
, IDC_TEXTBOX
);
152 DWORD dwStart
, dwEnd
;
154 // Acquire selection limits
155 SendMessage(hText
, EM_GETSEL
, (WPARAM
)&dwStart
, (LPARAM
)&dwEnd
);
157 // Test if the whose text is unselected
158 if(dwStart
== dwEnd
) {
160 // Select the whole text
161 SendMessageW(hText
, EM_SETSEL
, 0, -1);
164 SendMessageW(hText
, WM_COPY
, 0, 0);
166 // Restore previous values
167 SendMessageW(hText
, EM_SETSEL
, (WPARAM
)dwStart
, (LPARAM
)dwEnd
);
172 SendMessageW(hText
, WM_COPY
, 0, 0);
176 // Recover charset for the given font
179 GetFontMetrics(HWND hWnd
, HFONT hFont
)
186 hOldObj
= SelectObject(hDC
, hFont
);
187 GetTextMetrics(hDC
, &tmFont
);
188 SelectObject(hDC
, hOldObj
);
189 ReleaseDC(hWnd
, hDC
);
191 return tmFont
.tmCharSet
;
194 // Select a new character
197 AddCharToSelection(HWND hDlg
, WCHAR ch
)
199 HWND hMap
= GetDlgItem(hDlg
, IDC_FONTMAP
);
200 HWND hText
= GetDlgItem(hDlg
, IDC_TEXTBOX
);
205 // Retrieve current character selected
208 ch
= (WCHAR
) SendMessageW(hMap
, FM_GETCHAR
, 0, 0);
213 // Retrieve current selected font
214 hFont
= (HFONT
)SendMessage(hMap
, FM_GETHFONT
, 0, 0);
216 // Recover LOGFONT structure from hFont
217 if (!GetObject(hFont
, sizeof(LOGFONT
), &lFont
))
220 // Recover font properties of Richedit control
221 ZeroMemory(&cf
, sizeof(cf
));
222 cf
.cbSize
= sizeof(cf
);
223 SendMessage(hText
, EM_GETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&cf
);
225 // Apply properties of the new font
226 cf
.bCharSet
= GetFontMetrics(hText
, hFont
);
229 wcscpy(cf
.szFaceName
, lFont
.lfFaceName
);
231 // Update font properties
232 SendMessage(hText
, EM_SETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&cf
);
234 // Send selected character to Richedit
235 SendMessage(hText
, WM_CHAR
, (WPARAM
)ch
, 0);
241 UpdateSettings(HWND hDlg
)
243 if (hDlg
== hCharmapDlg
)
245 Settings
.IsAdvancedView
=
246 SendDlgItemMessage(hDlg
, IDC_CHECK_ADVANCED
, BM_GETCHECK
, 0, 0);
249 if (hDlg
== hAdvancedDlg
)
256 ChangeView(HWND hWnd
)
266 UINT DeskTopWidth
, DeskTopHeight
;
268 GetClientRect(hCharmapDlg
, &rcCharmap
);
269 GetClientRect(hAdvancedDlg
, &rcAdvanced
);
270 GetWindowRect(hWnd
, &rcPanelExt
);
271 GetClientRect(hWnd
, &rcPanelInt
);
272 GetClientRect(hStatusWnd
, &rcStatus
);
274 DeskTopWidth
= GetSystemMetrics(SM_CXFULLSCREEN
);
275 DeskTopHeight
= GetSystemMetrics(SM_CYFULLSCREEN
);
277 DeX
= (rcPanelExt
.right
- rcPanelExt
.left
) - rcPanelInt
.right
;
278 DeY
= (rcPanelExt
.bottom
- rcPanelExt
.top
) - rcPanelInt
.bottom
;
280 MoveWindow(hCharmapDlg
, 0, 0, rcCharmap
.right
, rcCharmap
.bottom
, FALSE
);
281 MoveWindow(hAdvancedDlg
, 0, rcCharmap
.bottom
, rcAdvanced
.right
, rcAdvanced
.bottom
, FALSE
);
283 ShowWindow(hAdvancedDlg
, (Settings
.IsAdvancedView
) ? SW_SHOW
: SW_HIDE
);
285 xPos
= rcPanelExt
.left
;
286 yPos
= rcPanelExt
.top
;
288 Width
= DeX
+ rcCharmap
.right
;
289 Height
= DeY
+ rcCharmap
.bottom
+ rcStatus
.bottom
;
291 if (Settings
.IsAdvancedView
)
292 Height
+= rcAdvanced
.bottom
;
294 if ((xPos
+ Width
) > DeskTopWidth
)
295 xPos
+= DeskTopWidth
- (xPos
+ Width
);
297 if ((yPos
+ Height
) > DeskTopHeight
)
298 yPos
+= DeskTopHeight
- (yPos
+ Height
);
309 CharMapDlgProc(HWND hDlg
,
320 FillFontStyleComboList(GetDlgItem(hDlg
,
325 // Configure Richedi control for sending notification changes.
326 evMask
= SendDlgItemMessage(hDlg
, IDC_TEXTBOX
, EM_GETEVENTMASK
, 0, 0);
327 evMask
|= ENM_CHANGE
;
328 SendDlgItemMessage(hDlg
, IDC_TEXTBOX
, EM_SETEVENTMASK
, 0, (LPARAM
)evMask
);
335 switch(LOWORD(wParam
))
338 switch (HIWORD(wParam
))
341 AddCharToSelection(hDlg
, LOWORD(lParam
));
347 if (HIWORD(wParam
) == CBN_SELCHANGE
)
354 AddCharToSelection(hDlg
, 0);
358 switch (HIWORD(wParam
)) {
360 if (GetWindowTextLength(GetDlgItem(hDlg
, IDC_TEXTBOX
)) == 0)
361 EnableWindow(GetDlgItem(hDlg
, IDC_COPY
), FALSE
);
363 EnableWindow(GetDlgItem(hDlg
, IDC_COPY
), TRUE
);
369 CopyCharacters(hDlg
);
372 case IDC_CHECK_ADVANCED
:
373 UpdateSettings(hDlg
);
374 ChangeView(GetParent(hDlg
));
390 AdvancedDlgProc(HWND hDlg
,
408 OnCreate(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
411 WCHAR lpAboutText
[256];
413 hCharmapDlg
= CreateDialog(hInstance
,
414 MAKEINTRESOURCE(IDD_CHARMAP
),
418 hAdvancedDlg
= CreateDialog(hInstance
,
419 MAKEINTRESOURCE(IDD_ADVANCED
),
423 hStatusWnd
= CreateWindow(STATUSCLASSNAME
,
425 WS_CHILD
| WS_VISIBLE
,
428 (HMENU
)IDD_STATUSBAR
,
432 // Set the status bar for multiple parts output
433 SendMessage(hStatusWnd
, SB_SIMPLE
, (WPARAM
)FALSE
, (LPARAM
)0);
437 hSysMenu
= GetSystemMenu(hWnd
, FALSE
);
439 if (hSysMenu
!= NULL
)
441 if (LoadStringW(hInstance
, IDS_ABOUT
, lpAboutText
, SIZEOF(lpAboutText
)))
443 AppendMenuW(hSysMenu
, MF_SEPARATOR
, 0, NULL
);
444 AppendMenuW(hSysMenu
, MF_STRING
, ID_ABOUT
, lpAboutText
);
451 static LRESULT CALLBACK
452 PanelWndProc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
456 return OnCreate(hWnd
, wParam
, lParam
);
463 SendMessage(hStatusWnd
, msg
, wParam
, lParam
);
480 return DefWindowProc(hWnd
, msg
, wParam
, lParam
);
484 InitInstance(HINSTANCE hInst
)
486 WCHAR szClass
[] = L
"CharMap";
491 LoadStringW(hInst
, IDS_TITLE
, szTitle
, SIZEOF(szTitle
));
493 hSmIcon
= LoadImage(hInstance
,
494 MAKEINTRESOURCE(IDI_ICON
),
500 hBgIcon
= LoadImage(hInstance
,
501 MAKEINTRESOURCE(IDI_ICON
),
508 ZeroMemory(&wc
, sizeof(wc
));
510 wc
.cbSize
= sizeof(wc
);
511 wc
.lpfnWndProc
= PanelWndProc
;
512 wc
.hInstance
= hInst
;
514 wc
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
515 wc
.hbrBackground
= (HBRUSH
)GetStockObject(NULL_BRUSH
);
516 wc
.lpszMenuName
= NULL
;
517 wc
.lpszClassName
= szClass
;
518 wc
.hIconSm
= hSmIcon
;
520 RegisterClassExW(&wc
);
522 hWnd
= CreateWindowW(
525 WS_CAPTION
| WS_SYSMENU
| WS_MINIMIZEBOX
,
537 ShowWindow(hWnd
, SW_SHOW
);
546 wWinMain(HINSTANCE hInst
,
551 INITCOMMONCONTROLSEX iccx
;
558 iccx
.dwSize
= sizeof(INITCOMMONCONTROLSEX
);
559 iccx
.dwICC
= ICC_TAB_CLASSES
;
560 InitCommonControlsEx(&iccx
);
562 if (RegisterMapClasses(hInstance
))
564 hRichEd20
= LoadLibraryW(L
"RICHED20.DLL");
566 if (hRichEd20
!= NULL
)
572 if (GetMessage(&Msg
, NULL
, 0, 0) <= 0)
578 TranslateMessage(&Msg
);
579 DispatchMessage(&Msg
);
582 FreeLibrary(hRichEd20
);
584 UnregisterMapClasses(hInstance
);