759 lines
26 KiB
C++
759 lines
26 KiB
C++
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
|
// PARTICULAR PURPOSE.
|
|
//
|
|
// Copyright (c) Microsoft Corporation. All rights reserved
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "ChooseFont.h"
|
|
#include "FontEnumeration.h"
|
|
#include "GdiTextRenderer.h"
|
|
#include "resource.h"
|
|
|
|
HINSTANCE g_hInstance;
|
|
IDWriteFactory* g_dwrite = NULL;
|
|
|
|
|
|
/******************************************************************
|
|
* *
|
|
* The ChooseFontDialog class controls all the UI associated with *
|
|
* the dialog and uses the support routines in FontEnumeration.cpp *
|
|
* to enumerate fonts and get various information about each one. *
|
|
* *
|
|
******************************************************************/
|
|
|
|
class ChooseFontDialog
|
|
{
|
|
public:
|
|
|
|
ChooseFontDialog();
|
|
|
|
HRESULT GetTextFormat(IDWriteTextFormat** textFormat);
|
|
HRESULT GetTextFormat(IDWriteTextFormat* textFormatIn, IDWriteTextFormat** textFormatOut);
|
|
|
|
~ChooseFontDialog();
|
|
|
|
private:
|
|
|
|
HWND m_dialog;
|
|
WCHAR m_localeName[LOCALE_NAME_MAX_LENGTH];
|
|
IDWriteFontCollection* m_fontCollection;
|
|
IDWriteTextFormat* m_currentTextFormat;
|
|
|
|
HRESULT OnFontFamilySelect();
|
|
HRESULT OnFontFaceSelect();
|
|
HRESULT OnFontSizeSelect();
|
|
|
|
HRESULT OnFontFamilyNameEdit(HWND hwndFontFamilies);
|
|
HRESULT OnFontFaceNameEdit(HWND hwndFontFaces);
|
|
HRESULT OnFontSizeNameEdit(HWND hwndFontSizes);
|
|
|
|
HRESULT DrawSampleText(HDC sampleDC);
|
|
|
|
static INT_PTR CALLBACK DialogProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
|
|
|
|
BOOL OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam);
|
|
void OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify);
|
|
void OnDrawItem(HWND hwnd, const DRAWITEMSTRUCT* lpDrawItem);
|
|
};
|
|
|
|
|
|
/******************************************************************
|
|
* *
|
|
* ChooseFontDialog::ChooseFontDialog *
|
|
* *
|
|
* Prepare to display the dialog *
|
|
* *
|
|
******************************************************************/
|
|
|
|
ChooseFontDialog::ChooseFontDialog()
|
|
: m_dialog(NULL),
|
|
m_fontCollection(),
|
|
m_currentTextFormat()
|
|
{
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* *
|
|
* ChooseFontDialog::~ChooseFontDialog *
|
|
* *
|
|
* Clean up resources *
|
|
* *
|
|
******************************************************************/
|
|
|
|
ChooseFontDialog::~ChooseFontDialog()
|
|
{
|
|
SafeRelease(&m_fontCollection);
|
|
SafeRelease(&m_currentTextFormat);
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* *
|
|
* ChooseFontDialog::ChooseFontDialog *
|
|
* *
|
|
* Create and display the dialog initialized to default attributes *
|
|
* *
|
|
******************************************************************/
|
|
|
|
HRESULT ChooseFontDialog::GetTextFormat(IDWriteTextFormat** textFormat)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
*textFormat = NULL;
|
|
|
|
// Default to the system font collection
|
|
SafeRelease(&m_fontCollection);
|
|
hr = g_dwrite->GetSystemFontCollection(&m_fontCollection);
|
|
|
|
// Default to the users' locale
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SNAME, &m_localeName[0], ARRAYSIZE(m_localeName));
|
|
}
|
|
|
|
// Create a default text format
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
SafeRelease(&m_currentTextFormat);
|
|
hr = g_dwrite->CreateTextFormat(
|
|
L"Segoe UI",
|
|
m_fontCollection,
|
|
DWRITE_FONT_WEIGHT_REGULAR,
|
|
DWRITE_FONT_STYLE_NORMAL,
|
|
DWRITE_FONT_STRETCH_NORMAL,
|
|
10.0f,
|
|
m_localeName,
|
|
&m_currentTextFormat);
|
|
}
|
|
|
|
// Open the dialog
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = (HRESULT) DialogBoxParam(g_hInstance, L"ChooseFont", NULL, DialogProc, (LPARAM) this);
|
|
}
|
|
|
|
// If all went well, and the user didn't cancel, return the new format.
|
|
if (hr == S_OK)
|
|
*textFormat = SafeDetach(&m_currentTextFormat);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* *
|
|
* ChooseFontDialog::ChooseFontDialog *
|
|
* *
|
|
* Create and display the dialog initialized to attributes in an *
|
|
* already existing text format. *
|
|
* *
|
|
******************************************************************/
|
|
|
|
HRESULT ChooseFontDialog::GetTextFormat(IDWriteTextFormat* textFormatIn, IDWriteTextFormat** textFormatOut)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
*textFormatOut = NULL;
|
|
|
|
SafeSet(&m_currentTextFormat, textFormatIn);
|
|
|
|
// Pull out the input font attributes
|
|
SafeRelease(&m_fontCollection);
|
|
hr = m_currentTextFormat->GetFontCollection(&m_fontCollection);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = m_currentTextFormat->GetLocaleName(&m_localeName[0], ARRAYSIZE(m_localeName));
|
|
}
|
|
|
|
// Open the dialog
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = (HRESULT) DialogBoxParam(g_hInstance, L"ChooseFont", NULL, DialogProc, (LPARAM) this);
|
|
}
|
|
|
|
// If all went well, and the user didn't cancel, return the new format.
|
|
if (hr == S_OK)
|
|
*textFormatOut = SafeDetach(&m_currentTextFormat);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* *
|
|
* ChooseFontDialog::OnFontFamilySelect *
|
|
* *
|
|
* Update the font face list to match the newly select font family *
|
|
* *
|
|
******************************************************************/
|
|
|
|
HRESULT ChooseFontDialog::OnFontFamilySelect()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
HWND hwndFontFamilyNames = GetDlgItem(m_dialog, ID_FONT_FAMILY_NAMES);
|
|
HWND hwndFontFaceNames = GetDlgItem(m_dialog, ID_FONT_FACE_NAMES);
|
|
int currentSelection = ComboBox_GetCurSel(hwndFontFamilyNames);
|
|
|
|
// Get the font family name
|
|
WCHAR fontFamilyName[100];
|
|
|
|
UINT32 fontFamilyNameLength = ComboBox_GetLBTextLen(hwndFontFamilyNames, currentSelection) + 1;
|
|
if (fontFamilyNameLength > ARRAYSIZE(fontFamilyName))
|
|
hr = E_NOT_SUFFICIENT_BUFFER;
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
ComboBox_GetLBText(hwndFontFamilyNames, currentSelection, &fontFamilyName[0]);
|
|
}
|
|
|
|
// Get the face names for the new font family
|
|
IDWriteFontFamily* fontFamily = NULL;
|
|
std::vector<IDWriteFont*> fonts;
|
|
|
|
// Get the font variants for this family
|
|
if (currentSelection != CB_ERR)
|
|
hr = GetFonts(m_fontCollection, fontFamilyName, fonts);
|
|
|
|
// Initialize the face name list
|
|
std::vector<FontFaceInfo> fontFaceInfo;
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
ComboBox_ResetContent(hwndFontFaceNames);
|
|
GetFontFaceInfo(fonts, m_localeName, fontFaceInfo);
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
for (size_t i = 0; i != fontFaceInfo.size(); ++i)
|
|
{
|
|
int fontFaceIndex = ComboBox_AddString(hwndFontFaceNames, fontFaceInfo[i].fontFaceName);
|
|
ComboBox_SetItemData(hwndFontFaceNames, fontFaceIndex, fontFaceInfo[i].PackedFontAttributes());
|
|
}
|
|
}
|
|
|
|
// Select the best fit font face for the current attributes
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
FontFaceInfo desiredAttributes(
|
|
L"",
|
|
m_currentTextFormat->GetFontWeight(),
|
|
m_currentTextFormat->GetFontStyle(),
|
|
m_currentTextFormat->GetFontStretch());
|
|
|
|
int selectedFontFaceName = 0;
|
|
ULONG bestFitAttributes = GetBestFontAttributes(m_fontCollection, fontFamilyName, desiredAttributes);
|
|
|
|
int fontFaceCount = ComboBox_GetCount(hwndFontFaceNames);
|
|
|
|
for (int i = 0; i != fontFaceCount; ++i)
|
|
{
|
|
if ((ULONG)ComboBox_GetItemData(hwndFontFaceNames, i) == bestFitAttributes)
|
|
{
|
|
selectedFontFaceName = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
ComboBox_SetCurSel(hwndFontFaceNames, selectedFontFaceName);
|
|
OnFontFaceSelect();
|
|
}
|
|
|
|
// Release the held font list.
|
|
for (size_t i = 0, ci = fonts.size(); i < ci; ++i)
|
|
{
|
|
SafeRelease(&fonts[i]);
|
|
}
|
|
SafeRelease(&fontFamily);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* *
|
|
* ChooseFontDialog::OnFontFaceSelect *
|
|
* *
|
|
* Record the new font face selection and redraw the sample text. *
|
|
* *
|
|
******************************************************************/
|
|
|
|
HRESULT ChooseFontDialog::OnFontFaceSelect()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// Signal the sample text window to redraw itself.
|
|
InvalidateRect(GetDlgItem(m_dialog, ID_SAMPLE_BOX), NULL, false);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* *
|
|
* ChooseFontDialog::OnFontSizeSelect *
|
|
* *
|
|
* Record the new font size and redraw the sample text. *
|
|
* *
|
|
******************************************************************/
|
|
|
|
HRESULT ChooseFontDialog::OnFontSizeSelect()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// Signal the sample text window to redraw itself.
|
|
InvalidateRect(GetDlgItem(m_dialog, ID_SAMPLE_BOX), NULL, false);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* *
|
|
* ChooseFontDialog::OnFontFamilyNameEdit *
|
|
* *
|
|
* Watch what is typed into the edit portion of the font family *
|
|
* combo and automatically select a name if a match is found. As *
|
|
* an added feature, also match against localized forms of the *
|
|
* family name. For example the user can type "Meiryo" on a *
|
|
* Japanese system and it will be found even though it's displayed *
|
|
* using a localized variant of the name. *
|
|
* *
|
|
******************************************************************/
|
|
|
|
HRESULT ChooseFontDialog::OnFontFamilyNameEdit(HWND hwndFontFamilies)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// Save the state of the edit box selection
|
|
DWORD editSelection = ComboBox_GetEditSel(hwndFontFamilies);
|
|
int editSelectionBegin = LOWORD(editSelection);
|
|
int editSelectionEnd = HIWORD(editSelection);
|
|
|
|
// Get the text in the edit portion of the combo
|
|
WCHAR fontFamilyName[100];
|
|
ComboBox_GetText(hwndFontFamilies, &fontFamilyName[0], ARRAYSIZE(fontFamilyName));
|
|
|
|
// Try to find an exact match (case-insensitive)
|
|
int matchingFontFamily = ComboBox_FindStringExact(hwndFontFamilies, -1, fontFamilyName);
|
|
bool usedAltMatch = false;
|
|
|
|
if (matchingFontFamily == CB_ERR)
|
|
{
|
|
// If a match isn't found, scan all for alternate forms in the font
|
|
// collection.
|
|
IDWriteFontFamily* fontFamily = NULL;
|
|
hr = GetFontFamily(m_fontCollection, fontFamilyName, &fontFamily);
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
// If a match is found, get the family name localized to the locale
|
|
// we're using in the combo box and match against that.
|
|
usedAltMatch = true;
|
|
|
|
std::wstring localFontFamilyName;
|
|
hr = GetFontFamilyName(fontFamily, m_localeName, localFontFamilyName);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
matchingFontFamily = ComboBox_FindStringExact(hwndFontFamilies, -1, localFontFamilyName.c_str());
|
|
}
|
|
}
|
|
else if (hr == DWRITE_E_NOFONT)
|
|
{
|
|
// Ignore DWRITE_E_NOFONT errors
|
|
hr = S_OK;
|
|
}
|
|
|
|
SafeRelease(&fontFamily);
|
|
}
|
|
|
|
// Process the match, if any
|
|
if (SUCCEEDED(hr) && matchingFontFamily != CB_ERR)
|
|
{
|
|
ComboBox_SetCurSel(hwndFontFamilies, matchingFontFamily);
|
|
|
|
// SetCurSel will update the edit text to match the text of the
|
|
// selected item. If we matched against an alternate name put that
|
|
// name back.
|
|
if (usedAltMatch)
|
|
ComboBox_SetText(hwndFontFamilies, fontFamilyName);
|
|
|
|
// Reset the edit selection to what is was before SetCurSel.
|
|
ComboBox_SetEditSel(hwndFontFamilies, editSelectionBegin, editSelectionEnd);
|
|
|
|
hr = OnFontFamilySelect();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* *
|
|
* ChooseFontDialog::OnFontFaceNameEdit *
|
|
* *
|
|
* Watch what is typed into the edit portion of the font face *
|
|
* combo and automatically select a name if a match is found. *
|
|
* *
|
|
******************************************************************/
|
|
|
|
HRESULT ChooseFontDialog::OnFontFaceNameEdit(HWND hwnd)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// Save the state of the edit box selection
|
|
DWORD editSelection = ComboBox_GetEditSel(hwnd);
|
|
int editSelectionBegin = LOWORD(editSelection);
|
|
int editSelectionEnd = HIWORD(editSelection);
|
|
|
|
// Try to find the currently typed text
|
|
WCHAR text[100];
|
|
ComboBox_GetText(hwnd, &text[0], ARRAYSIZE(text));
|
|
|
|
int selectedItem = ComboBox_FindStringExact(hwnd, -1, text);
|
|
if (selectedItem != CB_ERR)
|
|
{
|
|
// If text is found, select the corresponding list item, put the
|
|
// selection state back to what it was originally, and redraw the
|
|
// sample text
|
|
ComboBox_SetCurSel(hwnd, selectedItem);
|
|
ComboBox_SetEditSel(hwnd, editSelectionBegin, editSelectionEnd);
|
|
hr = OnFontFaceSelect();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* *
|
|
* ChooseFontDialog::OnFontSizeNameEdit *
|
|
* *
|
|
* Watch what is typed into the edit portion of the font size *
|
|
* combo and automatically select a name if a match is found. *
|
|
* *
|
|
******************************************************************/
|
|
|
|
HRESULT ChooseFontDialog::OnFontSizeNameEdit(HWND hwnd)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// Save the state of the edit box selection
|
|
DWORD editSelection = ComboBox_GetEditSel(hwnd);
|
|
int editSelectionBegin = LOWORD(editSelection);
|
|
int editSelectionEnd = HIWORD(editSelection);
|
|
|
|
// Try to find the currently typed text
|
|
WCHAR text[100];
|
|
ComboBox_GetText(hwnd, &text[0], ARRAYSIZE(text));
|
|
|
|
int selectedItem = ComboBox_FindStringExact(hwnd, -1, text);
|
|
if (selectedItem != CB_ERR)
|
|
{
|
|
// If text is found, select the corresponding list item, put the
|
|
// selection state back to what it was originally, and redraw the
|
|
// sample text
|
|
ComboBox_SetCurSel(hwnd, selectedItem);
|
|
ComboBox_SetEditSel(hwnd, editSelectionBegin, editSelectionEnd);
|
|
}
|
|
hr = OnFontSizeSelect();
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* *
|
|
* ChooseFontDialog::DrawSampleText *
|
|
* *
|
|
******************************************************************/
|
|
|
|
HRESULT ChooseFontDialog::DrawSampleText(HDC sampleDC)
|
|
{
|
|
static WCHAR sampleText[] = L"The quick brown fox jumps over the lazy dog";
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
HWND hwndFontFamilies = GetDlgItem(m_dialog, ID_FONT_FAMILY_NAMES);
|
|
HWND hwndFontFaces = GetDlgItem(m_dialog, ID_FONT_FACE_NAMES);
|
|
HWND hwndFontSizes = GetDlgItem(m_dialog, ID_FONT_SIZE);
|
|
HWND hwndSampleBox = GetDlgItem(m_dialog, ID_SAMPLE_BOX);
|
|
|
|
// Get the currently selected font family. If there isn't one, then just
|
|
// don't update the text format and continue to use whatever we had before
|
|
int selectedFontFamily = ComboBox_GetCurSel(hwndFontFamilies);
|
|
|
|
if (selectedFontFamily != CB_ERR)
|
|
{
|
|
// Get the font family name
|
|
WCHAR fontFamilyName[100];
|
|
GetWindowText(hwndFontFamilies, &fontFamilyName[0], ARRAYSIZE(fontFamilyName));
|
|
|
|
// Get the font face attributes
|
|
int selectedFontFace = ComboBox_GetCurSel(hwndFontFaces);
|
|
ULONG packedAttributes = (ULONG) ComboBox_GetItemData(hwndFontFaces, selectedFontFace);
|
|
|
|
// Get the font size
|
|
WCHAR fontSizeText[100];
|
|
GetWindowText(hwndFontSizes, &fontSizeText[0], ARRAYSIZE(fontSizeText));
|
|
|
|
float pointSize = float(wcstod(fontSizeText, NULL));
|
|
if (pointSize <= 0)
|
|
pointSize = 10;
|
|
|
|
float dipSize = pointSize * 96 / 72;
|
|
|
|
FontFaceInfo fontFaceInfo(fontFamilyName, packedAttributes);
|
|
|
|
// Recreate the text format object
|
|
SafeRelease(&m_currentTextFormat);
|
|
hr = g_dwrite->CreateTextFormat(
|
|
fontFamilyName,
|
|
m_fontCollection,
|
|
fontFaceInfo.fontWeight,
|
|
fontFaceInfo.fontStyle,
|
|
fontFaceInfo.fontStretch,
|
|
dipSize,
|
|
m_localeName,
|
|
&m_currentTextFormat);
|
|
}
|
|
|
|
// Get the size of the sample box
|
|
RECT sampleBounds = {};
|
|
GetClientRect(hwndSampleBox, &sampleBounds);
|
|
|
|
UINT width = sampleBounds.right - sampleBounds.left;
|
|
UINT height = sampleBounds.bottom - sampleBounds.top;
|
|
|
|
// Layout the sample text using the text format and UI bounds (converted to DIPs)
|
|
IDWriteTextLayout* textLayout = NULL;
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = g_dwrite->CreateTextLayout(
|
|
sampleText,
|
|
ARRAYSIZE(sampleText) - 1,
|
|
m_currentTextFormat,
|
|
(float) width * 96.0f / GetDeviceCaps(sampleDC, LOGPIXELSY),
|
|
(float) height * 96.0f / GetDeviceCaps(sampleDC, LOGPIXELSY),
|
|
&textLayout);
|
|
}
|
|
|
|
// Create a DWrite surface to render to
|
|
GdiTextRenderer* textRenderer = NULL;
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
textRenderer = SafeAcquire(new(std::nothrow) GdiTextRenderer());
|
|
if (textRenderer != NULL)
|
|
hr = textRenderer->Initialize(m_dialog, sampleDC, width, height);
|
|
else
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Fill the DWrite surface with the background color
|
|
HDC dwriteDC = textRenderer->GetDC();
|
|
SetDCBrushColor(dwriteDC, GetSysColor(COLOR_BTNFACE));
|
|
FillRect(dwriteDC, &sampleBounds, GetStockBrush(DC_BRUSH));
|
|
|
|
// Draw the text onto the DWrite surface
|
|
hr = textLayout->Draw(NULL, textRenderer, 0, 0);
|
|
|
|
// Copy the DWrite surface to the sample on screen
|
|
BitBlt(
|
|
sampleDC,
|
|
0,
|
|
0,
|
|
width,
|
|
height,
|
|
dwriteDC,
|
|
0,
|
|
0,
|
|
SRCCOPY | NOMIRRORBITMAP);
|
|
}
|
|
|
|
SafeRelease(&textRenderer);
|
|
SafeRelease(&textLayout);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* *
|
|
* ChooseFontDialog::WndProc *
|
|
* *
|
|
* Dispatch window message to the appropriate hander *
|
|
* *
|
|
******************************************************************/
|
|
|
|
INT_PTR CALLBACK ChooseFontDialog::DialogProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
if (message == WM_INITDIALOG)
|
|
SetWindowLongPtr(hWnd, GWLP_USERDATA, lParam);
|
|
|
|
ChooseFontDialog* this_ = (ChooseFontDialog*) GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
|
|
|
if (this_ != NULL)
|
|
{
|
|
switch (message)
|
|
{
|
|
HANDLE_MSG(hWnd, WM_INITDIALOG, this_->OnInitDialog);
|
|
HANDLE_MSG(hWnd, WM_COMMAND, this_->OnCommand);
|
|
HANDLE_MSG(hWnd, WM_DRAWITEM, this_->OnDrawItem);
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* *
|
|
* ChooseFontDialog::OnInitDialog *
|
|
* *
|
|
* Initialize the dialog by enumerating the font families and *
|
|
* setting up a hardcoded list of standard font sizes. *
|
|
* *
|
|
******************************************************************/
|
|
|
|
BOOL ChooseFontDialog::OnInitDialog(HWND dialog, HWND hwndFocus, LPARAM lParam)
|
|
{
|
|
m_dialog = dialog;
|
|
|
|
HWND hwndFamilyNames = GetDlgItem(dialog, ID_FONT_FAMILY_NAMES);
|
|
HWND hwndSizes = GetDlgItem(dialog, ID_FONT_SIZE);
|
|
|
|
// Fill in the font family name list.
|
|
|
|
std::vector<std::wstring> fontFamilyNames;
|
|
if (FAILED(GetFontFamilyNames(m_fontCollection, m_localeName, fontFamilyNames)))
|
|
return FALSE;
|
|
|
|
for (size_t i = 0; i != fontFamilyNames.size(); ++i)
|
|
ComboBox_AddString(hwndFamilyNames, fontFamilyNames[i].c_str());
|
|
|
|
// Fill in the hardcoded font sizes
|
|
|
|
static const float FontSizes[] = {
|
|
1.5, 3.5, 4.5, 6,
|
|
8, 9, 10, 11, 12, 14, 16, 18,
|
|
20, 22, 24, 26, 28, 36, 48, 72
|
|
};
|
|
|
|
WCHAR sizeName[100];
|
|
sizeName[0] = '\0';
|
|
|
|
for (int i = 0; i != ARRAYSIZE(FontSizes); ++i)
|
|
{
|
|
StringCchPrintf(sizeName, ARRAYSIZE(sizeName), L"%.3G", FontSizes[i]);
|
|
ComboBox_AddString(hwndSizes, sizeName);
|
|
}
|
|
|
|
// Select the current size
|
|
|
|
StringCchPrintf(sizeName, ARRAYSIZE(sizeName), L"%0.0f", m_currentTextFormat->GetFontSize());
|
|
|
|
SetWindowText(hwndSizes, sizeName);
|
|
if (CB_ERR == ComboBox_SelectString(hwndSizes, -1, sizeName))
|
|
SetWindowText(hwndSizes, sizeName);
|
|
|
|
// Select the font family specified in the input text format.
|
|
|
|
int selectedFontFamily = CB_ERR;
|
|
std::wstring fontFamilyName;
|
|
|
|
if (SUCCEEDED(GetFontFamilyNameFromFormat(m_currentTextFormat, fontFamilyName)))
|
|
{
|
|
selectedFontFamily = ComboBox_SelectString(hwndFamilyNames, -1, fontFamilyName.c_str());
|
|
}
|
|
|
|
if (selectedFontFamily == CB_ERR)
|
|
SetWindowText(hwndFamilyNames, fontFamilyName.c_str());
|
|
|
|
OnFontFamilySelect();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* *
|
|
* ChooseFontDialog::OnCommand *
|
|
* *
|
|
* Dispatch button clicks, changing listbox selections, etc. *
|
|
* *
|
|
******************************************************************/
|
|
|
|
void ChooseFontDialog::OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
|
|
{
|
|
if (id == IDCANCEL && codeNotify == BN_CLICKED)
|
|
EndDialog(hwnd, S_FALSE);
|
|
|
|
else if (id == IDOK && codeNotify == BN_CLICKED)
|
|
EndDialog(hwnd, S_OK);
|
|
|
|
else if (id == ID_FONT_FAMILY_NAMES && codeNotify == CBN_SELCHANGE)
|
|
OnFontFamilySelect();
|
|
|
|
else if (id == ID_FONT_FAMILY_NAMES && codeNotify == CBN_EDITCHANGE)
|
|
OnFontFamilyNameEdit(hwndCtl);
|
|
|
|
else if (id == ID_FONT_FACE_NAMES && codeNotify == CBN_SELCHANGE)
|
|
OnFontFaceSelect();
|
|
|
|
else if (id == ID_FONT_FACE_NAMES && codeNotify == CBN_EDITCHANGE)
|
|
OnFontFaceNameEdit(hwndCtl);
|
|
|
|
else if (id == ID_FONT_SIZE && codeNotify == CBN_SELCHANGE)
|
|
OnFontSizeSelect();
|
|
|
|
else if (id == ID_FONT_SIZE && codeNotify == CBN_EDITCHANGE)
|
|
OnFontSizeNameEdit(hwndCtl);
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* *
|
|
* ChooseFontDialog::OnDrawItem *
|
|
* *
|
|
* Redraw the sample text whenever it's window needs updating *
|
|
* *
|
|
******************************************************************/
|
|
|
|
void ChooseFontDialog::OnDrawItem(HWND hwnd, const DRAWITEMSTRUCT* lpDrawItem)
|
|
{
|
|
DrawSampleText(lpDrawItem->hDC);
|
|
}
|
|
|
|
|
|
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR, int)
|
|
{
|
|
// The Microsoft Security Development Lifecycle recommends that all
|
|
// applications include the following call to ensure that heap corruptions
|
|
// do not go unnoticed and therefore do not introduce opportunities
|
|
// for security exploits.
|
|
HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
|
|
|
|
g_hInstance = hInstance;
|
|
|
|
DWriteCreateFactory(
|
|
DWRITE_FACTORY_TYPE_SHARED,
|
|
__uuidof(IDWriteFactory),
|
|
(IUnknown **) &g_dwrite);
|
|
|
|
{
|
|
ChooseFontDialog chooseFont;
|
|
|
|
IDWriteTextFormat* textFormatOut = NULL;
|
|
chooseFont.GetTextFormat(&textFormatOut);
|
|
|
|
SafeRelease(&textFormatOut);
|
|
}
|
|
SafeRelease(&g_dwrite);
|
|
} |