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>
22 /* Font-enumeration callback */
26 EnumFontNames(ENUMLOGFONTEXW
*lpelfe
,
27 NEWTEXTMETRICEXW
*lpntme
,
31 HWND hwndCombo
= (HWND
)lParam
;
32 LPWSTR pszName
= lpelfe
->elfLogFont
.lfFaceName
;
34 /* make sure font doesn't already exist in our list */
35 if(SendMessageW(hwndCombo
,
38 (LPARAM
)pszName
) == CB_ERR
)
45 idx
= (INT
)SendMessageW(hwndCombo
,
50 /* record the font's attributes (Fixedwidth and Truetype) */
51 fFixed
= (lpelfe
->elfLogFont
.lfPitchAndFamily
& FIXED_PITCH
) ? TRUE
: FALSE
;
52 fTrueType
= (lpelfe
->elfLogFont
.lfOutPrecision
== OUT_STROKE_PRECIS
) ? TRUE
: FALSE
;
54 /* store this information in the list-item's userdata area */
55 SendMessageW(hwndCombo
,
58 MAKEWPARAM(fFixed
, fTrueType
));
65 /* Initialize the font-list by enumeration all system fonts */
68 FillFontStyleComboList(HWND hwndCombo
)
73 /* FIXME: for fun, draw each font in its own style */
74 HFONT hFont
= GetStockObject(DEFAULT_GUI_FONT
);
75 SendMessageW(hwndCombo
,
80 ZeroMemory(&lf
, sizeof(lf
));
81 lf
.lfCharSet
= DEFAULT_CHARSET
;
83 hdc
= GetDC(hwndCombo
);
85 /* store the list of fonts in the combo */
86 EnumFontFamiliesExW(hdc
,
88 (FONTENUMPROCW
)EnumFontNames
,
95 SendMessageW(hwndCombo
,
104 ChangeMapFont(HWND hDlg
)
111 hCombo
= GetDlgItem(hDlg
, IDC_FONTCOMBO
);
113 Len
= GetWindowTextLengthW(hCombo
);
117 lpFontName
= HeapAlloc(GetProcessHeap(),
119 (Len
+ 1) * sizeof(WCHAR
));
128 hMap
= GetDlgItem(hDlg
, IDC_FONTMAP
);
136 HeapFree(GetProcessHeap(),
142 // Copy collected characters into the clipboard
145 CopyCharacters(HWND hDlg
)
147 HWND hText
= GetDlgItem(hDlg
, IDC_TEXTBOX
);
148 DWORD dwStart
, dwEnd
;
150 // Acquire selection limits
151 SendMessage(hText
, EM_GETSEL
, (WPARAM
)&dwStart
, (LPARAM
)&dwEnd
);
153 // Test if the whose text is unselected
154 if(dwStart
== dwEnd
) {
156 // Select the whole text
157 SendMessageW(hText
, EM_SETSEL
, 0, -1);
160 SendMessageW(hText
, WM_COPY
, 0, 0);
162 // Restore previous values
163 SendMessageW(hText
, EM_SETSEL
, (WPARAM
)dwStart
, (LPARAM
)dwEnd
);
168 SendMessageW(hText
, WM_COPY
, 0, 0);
172 // Recover charset for the given font
175 GetFontMetrics(HWND hWnd
, HFONT hFont
)
182 hOldObj
= SelectObject(hDC
, hFont
);
183 GetTextMetrics(hDC
, &tmFont
);
184 SelectObject(hDC
, hOldObj
);
185 ReleaseDC(hWnd
, hDC
);
187 return tmFont
.tmCharSet
;
190 // Select a new character
193 AddCharToSelection(HWND hDlg
, WCHAR ch
)
195 HWND hMap
= GetDlgItem(hDlg
, IDC_FONTMAP
);
196 HWND hText
= GetDlgItem(hDlg
, IDC_TEXTBOX
);
201 // Retrieve current character selected
204 ch
= (WCHAR
) SendMessageW(hMap
, FM_GETCHAR
, 0, 0);
209 // Retrieve current selected font
210 hFont
= (HFONT
)SendMessage(hMap
, FM_GETHFONT
, 0, 0);
212 // Recover LOGFONT structure from hFont
213 if (!GetObject(hFont
, sizeof(LOGFONT
), &lFont
))
216 // Recover font properties of Richedit control
217 ZeroMemory(&cf
, sizeof(cf
));
218 cf
.cbSize
= sizeof(cf
);
219 SendMessage(hText
, EM_GETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&cf
);
221 // Apply properties of the new font
222 cf
.bCharSet
= GetFontMetrics(hText
, hFont
);
225 wcscpy(cf
.szFaceName
, lFont
.lfFaceName
);
227 // Update font properties
228 SendMessage(hText
, EM_SETCHARFORMAT
, SCF_SELECTION
, (LPARAM
)&cf
);
230 // Send selected character to Richedit
231 SendMessage(hText
, WM_CHAR
, (WPARAM
)ch
, 0);
237 UpdateSettings(HWND hDlg
)
239 if (hDlg
== hCharmapDlg
)
241 Settings
.IsAdvancedView
=
242 SendDlgItemMessage(hDlg
, IDC_CHECK_ADVANCED
, BM_GETCHECK
, 0, 0);
245 if (hDlg
== hAdvancedDlg
)
252 ChangeView(HWND hWnd
)
262 UINT DeskTopWidth
, DeskTopHeight
;
264 GetClientRect(hCharmapDlg
, &rcCharmap
);
265 GetClientRect(hAdvancedDlg
, &rcAdvanced
);
266 GetWindowRect(hWnd
, &rcPanelExt
);
267 GetClientRect(hWnd
, &rcPanelInt
);
268 GetClientRect(hStatusWnd
, &rcStatus
);
270 DeskTopWidth
= GetSystemMetrics(SM_CXFULLSCREEN
);
271 DeskTopHeight
= GetSystemMetrics(SM_CYFULLSCREEN
);
273 DeX
= (rcPanelExt
.right
- rcPanelExt
.left
) - rcPanelInt
.right
;
274 DeY
= (rcPanelExt
.bottom
- rcPanelExt
.top
) - rcPanelInt
.bottom
;
276 MoveWindow(hCharmapDlg
, 0, 0, rcCharmap
.right
, rcCharmap
.bottom
, FALSE
);
277 MoveWindow(hAdvancedDlg
, 0, rcCharmap
.bottom
, rcAdvanced
.right
, rcAdvanced
.bottom
, FALSE
);
279 ShowWindow(hAdvancedDlg
, (Settings
.IsAdvancedView
) ? SW_SHOW
: SW_HIDE
);
281 xPos
= rcPanelExt
.left
;
282 yPos
= rcPanelExt
.top
;
284 Width
= DeX
+ rcCharmap
.right
;
285 Height
= DeY
+ rcCharmap
.bottom
+ rcStatus
.bottom
;
287 if (Settings
.IsAdvancedView
)
288 Height
+= rcAdvanced
.bottom
;
290 if ((xPos
+ Width
) > DeskTopWidth
)
291 xPos
+= DeskTopWidth
- (xPos
+ Width
);
293 if ((yPos
+ Height
) > DeskTopHeight
)
294 yPos
+= DeskTopHeight
- (yPos
+ Height
);
305 CharMapDlgProc(HWND hDlg
,
316 FillFontStyleComboList(GetDlgItem(hDlg
,
321 // Configure Richedi control for sending notification changes.
322 evMask
= SendDlgItemMessage(hDlg
, IDC_TEXTBOX
, EM_GETEVENTMASK
, 0, 0);
323 evMask
|= ENM_CHANGE
;
324 SendDlgItemMessage(hDlg
, IDC_TEXTBOX
, EM_SETEVENTMASK
, 0, (LPARAM
)evMask
);
331 switch(LOWORD(wParam
))
334 switch (HIWORD(wParam
))
337 AddCharToSelection(hDlg
, LOWORD(lParam
));
343 if (HIWORD(wParam
) == CBN_SELCHANGE
)
350 AddCharToSelection(hDlg
, 0);
354 switch (HIWORD(wParam
)) {
356 if (GetWindowTextLength(GetDlgItem(hDlg
, IDC_TEXTBOX
)) == 0)
357 EnableWindow(GetDlgItem(hDlg
, IDC_COPY
), FALSE
);
359 EnableWindow(GetDlgItem(hDlg
, IDC_COPY
), TRUE
);
365 CopyCharacters(hDlg
);
368 case IDC_CHECK_ADVANCED
:
369 UpdateSettings(hDlg
);
370 ChangeView(GetParent(hDlg
));
386 AdvancedDlgProc(HWND hDlg
,
404 OnCreate(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
407 WCHAR lpAboutText
[256];
409 hCharmapDlg
= CreateDialog(hInstance
,
410 MAKEINTRESOURCE(IDD_CHARMAP
),
414 hAdvancedDlg
= CreateDialog(hInstance
,
415 MAKEINTRESOURCE(IDD_ADVANCED
),
419 hStatusWnd
= CreateWindow(STATUSCLASSNAME
,
421 WS_CHILD
| WS_VISIBLE
,
424 (HMENU
)IDD_STATUSBAR
,
428 // Set the status bar for multiple parts output
429 SendMessage(hStatusWnd
, SB_SIMPLE
, (WPARAM
)FALSE
, (LPARAM
)0);
433 hSysMenu
= GetSystemMenu(hWnd
, FALSE
);
435 if (hSysMenu
!= NULL
)
437 if (LoadStringW(hInstance
, IDS_ABOUT
, lpAboutText
, SIZEOF(lpAboutText
)))
439 AppendMenuW(hSysMenu
, MF_SEPARATOR
, 0, NULL
);
440 AppendMenuW(hSysMenu
, MF_STRING
, ID_ABOUT
, lpAboutText
);
447 static LRESULT CALLBACK
448 PanelWndProc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
452 return OnCreate(hWnd
, wParam
, lParam
);
459 SendMessage(hStatusWnd
, msg
, wParam
, lParam
);
477 return DefWindowProc(hWnd
, msg
, wParam
, lParam
);
481 InitInstance(HINSTANCE hInst
)
483 WCHAR szClass
[] = L
"CharMap";
488 LoadStringW(hInst
, IDS_TITLE
, szTitle
, SIZEOF(szTitle
));
490 hSmIcon
= LoadImage(hInstance
,
491 MAKEINTRESOURCE(IDI_ICON
),
497 hBgIcon
= LoadImage(hInstance
,
498 MAKEINTRESOURCE(IDI_ICON
),
505 ZeroMemory(&wc
, sizeof(wc
));
507 wc
.cbSize
= sizeof(wc
);
508 wc
.lpfnWndProc
= PanelWndProc
;
509 wc
.hInstance
= hInst
;
511 wc
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
512 wc
.hbrBackground
= (HBRUSH
)GetStockObject(NULL_BRUSH
);
513 wc
.lpszMenuName
= NULL
;
514 wc
.lpszClassName
= szClass
;
515 wc
.hIconSm
= hSmIcon
;
517 RegisterClassExW(&wc
);
519 hWnd
= CreateWindowW(
522 WS_CAPTION
| WS_SYSMENU
| WS_MINIMIZEBOX
,
535 ShowWindow(hWnd
, SW_SHOW
);
544 wWinMain(HINSTANCE hInst
,
549 INITCOMMONCONTROLSEX iccx
;
556 iccx
.dwSize
= sizeof(INITCOMMONCONTROLSEX
);
557 iccx
.dwICC
= ICC_TAB_CLASSES
;
558 InitCommonControlsEx(&iccx
);
560 if (RegisterMapClasses(hInstance
))
562 hRichEd20
= LoadLibraryW(L
"RICHED20.DLL");
564 if (hRichEd20
!= NULL
)
570 if (GetMessage(&Msg
, NULL
, 0, 0) <= 0)
576 TranslateMessage(&Msg
);
577 DispatchMessage(&Msg
);
580 FreeLibrary(hRichEd20
);
582 UnregisterMapClasses(hInstance
);