#include <fcntl.h> // _O_WTEXT
#include <io.h> // _setmode
#include <stdio.h> // _fileno
#include <tchar.h>
#include <Windows.h>
#include "resource.h"
#define LINE_HEIGHT 48
// 関数プロトタイプ宣言
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int CALLBACK EnumFontFamExProc(const LOGFONT* lpelfe,
const TEXTMETRIC* lpntme, DWORD FontType, LPARAM lParam);
void OnCreate(HWND hWnd);
void OnSize(HWND hWnd);
void OnVScroll(HWND hWnd, WPARAM wParam, LPARAM lParam);
void OnMouseWheel(HWND hWnd, WPARAM wParam, LPARAM lParam);
int OnCommand(HWND hWnd, WPARAM wParam);
void OnPaint(HWND hWnd);
// グローバル変数
TCHAR g_atcClassName[] = _T("EnumFont");
TCHAR g_atcWindowName[] = _T("Enum Font");
SCROLLINFO g_siVert;
LOGFONT g_aLogFont[512];
int g_iFontNum = 0;
//==============================================================================
int APIENTRY _tWinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
WNDCLASSEX wcex;
HWND hWnd;
MSG msg;
HACCEL hAccelTable;
_setmode(_fileno(stdout), _O_WTEXT);
// ウィンドウクラスの登録
wcex.cbSize = sizeof wcex;
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = g_atcClassName;
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (RegisterClassEx(&wcex) == 0) {
return 0;
}
// ウィンドウの作成
hWnd = CreateWindow(
g_atcClassName, // ClassName
g_atcWindowName, // WindowName
WS_OVERLAPPEDWINDOW | WS_VSCROLL, // Style
CW_USEDEFAULT, // x
0, // y
CW_USEDEFAULT, // Width
0, // Height
NULL, // WndParent
NULL, // Menu
hInstance,
NULL);
if (hWnd == NULL) {
return 0;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDR_MAINFRAME);
while (GetMessage(&msg, NULL, 0, 0)) {
if (TranslateAccelerator(msg.hwnd, hAccelTable, &msg) == 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
//------------------------------------------------------------------------------
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg) {
case WM_PAINT:
OnPaint(hWnd);
break;
case WM_VSCROLL:
OnVScroll(hWnd, wParam, lParam);
break;
case WM_MOUSEWHEEL:
OnMouseWheel(hWnd, wParam, lParam);
break;
case WM_COMMAND:
if (OnCommand(hWnd, wParam)) {
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
break;
case WM_SIZE:
OnSize(hWnd);
break;
case WM_CREATE:
OnCreate(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
//------------------------------------------------------------------------------
int CALLBACK EnumFontFamExProc(const LOGFONT* lpelfe,
const TEXTMETRIC* lpntme, DWORD FontType, LPARAM lParam)
{
_tprintf(_T("%d,%d,\t%d,%d,%d,%d,%d,%d,%d,\t%d,%d,%d,%d,\t%s\n"),
lpelfe->lfHeight,
lpelfe->lfWidth,
lpelfe->lfEscapement,
lpelfe->lfOrientation,
lpelfe->lfWeight,
lpelfe->lfItalic,
lpelfe->lfUnderline,
lpelfe->lfStrikeOut,
lpelfe->lfCharSet,
lpelfe->lfOutPrecision,
lpelfe->lfClipPrecision,
lpelfe->lfQuality,
lpelfe->lfPitchAndFamily,
lpelfe->lfFaceName);
if (_countof(g_aLogFont) <= g_iFontNum) {
return 0; // 列挙停止
}
if (g_iFontNum == 0 ||
_tcscmp(g_aLogFont[g_iFontNum - 1].lfFaceName, lpelfe->lfFaceName)) {
g_aLogFont[g_iFontNum++] = *lpelfe;
}
return 1; // 列挙継続
}
//------------------------------------------------------------------------------
void OnCreate(HWND hWnd)
{
HDC hDC;
LOGFONT logfont;
RECT rcClient;
hDC = GetDC(NULL);
ZeroMemory(&logfont, sizeof logfont);
logfont.lfCharSet = DEFAULT_CHARSET;
EnumFontFamiliesEx(hDC, &logfont, EnumFontFamExProc, 0, 0);
ReleaseDC(NULL, hDC);
GetClientRect(hWnd, &rcClient);
g_siVert.cbSize = sizeof g_siVert;
g_siVert.fMask = SIF_RANGE | SIF_PAGE | SIF_POS | SIF_DISABLENOSCROLL;
g_siVert.nMin = 0;
g_siVert.nMax = LINE_HEIGHT * g_iFontNum - 1;
g_siVert.nPage = rcClient.bottom;
g_siVert.nPos = 0;
SetScrollInfo(hWnd, SB_VERT, &g_siVert, FALSE);
}
//------------------------------------------------------------------------------
void OnSize(HWND hWnd)
{
RECT rcClient;
int iPosMax;
GetClientRect(hWnd, &rcClient);
g_siVert.nPage = rcClient.bottom;
iPosMax = g_siVert.nMax - g_siVert.nPage + 1;
if (iPosMax < 0) {
iPosMax = 0;
}
if (iPosMax < g_siVert.nPos) {
g_siVert.nPos = iPosMax;
}
SetScrollInfo(hWnd, SB_VERT, &g_siVert, TRUE);
}
//------------------------------------------------------------------------------
// (HWND)lParam:handle to scroll bar
void OnVScroll(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
SCROLLINFO si;
int iPos;
int iPosMax;
iPos = g_siVert.nPos;
iPosMax = g_siVert.nMax - g_siVert.nPage + 1;
switch (LOWORD(wParam)) {
case SB_LINEUP: // 0
iPos -= LINE_HEIGHT;
break;
case SB_LINEDOWN: // 1
iPos += LINE_HEIGHT;
break;
case SB_PAGEUP: // 2
iPos -= g_siVert.nPage;
break;
case SB_PAGEDOWN: // 3
iPos += g_siVert.nPage;
break;
case SB_THUMBTRACK: // 5
si.cbSize = sizeof si;
si.fMask = SIF_TRACKPOS;
if (GetScrollInfo(hWnd, SB_VERT, &si) != 0) {
iPos = si.nTrackPos;
}
break;
case SB_TOP: // 6
iPos = 0;
break;
case SB_BOTTOM: // 7
iPos = iPosMax;
break;
}
iPos = min(iPos, iPosMax);
iPos = max(iPos, 0);
if (iPos == g_siVert.nPos) {
return;
}
ScrollWindowEx(hWnd, 0, g_siVert.nPos - iPos,
NULL, NULL, NULL, NULL, SW_INVALIDATE | SW_ERASE);
g_siVert.nPos = iPos;
SetScrollInfo(hWnd, SB_VERT, &g_siVert, TRUE);
UpdateWindow(hWnd);
}
//------------------------------------------------------------------------------
void OnMouseWheel(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
int nScrollCode;
short zDelta;
zDelta = HIWORD(wParam);
if (0 < zDelta) {
nScrollCode = SB_LINEUP;
} else {
nScrollCode = SB_LINEDOWN;
}
SendMessage(hWnd, WM_VSCROLL, nScrollCode, (LPARAM)NULL);
}
//------------------------------------------------------------------------------
int OnCommand(HWND hWnd, WPARAM wParam)
{
int nScrollCode;
switch (LOWORD(wParam)) {
case ID_PAGEUP:
nScrollCode = SB_PAGEUP;
break;
case ID_PAGEDOWN:
nScrollCode = SB_PAGEDOWN;
break;
case ID_END:
nScrollCode = SB_BOTTOM;
break;
case ID_HOME:
nScrollCode = SB_TOP;
break;
case ID_UP:
nScrollCode = SB_LINEUP;
break;
case ID_DOWN:
nScrollCode = SB_LINEDOWN;
break;
default:
return 1;
}
SendMessage(hWnd, WM_VSCROLL, nScrollCode, (LPARAM)NULL);
return 0;
}
//------------------------------------------------------------------------------
void OnPaint(HWND hWnd)
{
HDC hdc;
PAINTSTRUCT ps;
HFONT hFont;
HGDIOBJ hFontOld;
TCHAR atcFaceName[32];
TCHAR atcStr[] = _T("012abc日本語");
TCHAR* ptc;
int iStrLen;
int iY;
int i;
hdc = BeginPaint(hWnd, &ps);
iStrLen = _tcslen(atcStr);
for (i = 0; i < g_iFontNum; i++) {
iY = i * LINE_HEIGHT - g_siVert.nPos;
if (iY + LINE_HEIGHT < ps.rcPaint.top || ps.rcPaint.bottom < iY) {
continue;
}
ptc = g_aLogFont[i].lfFaceName;
TextOut(hdc, 0, iY, ptc, _tcslen(ptc));
hFont = CreateFontIndirect(g_aLogFont + i);
hFontOld = SelectObject(hdc, hFont);
GetTextFace(hdc, _countof(atcFaceName), atcFaceName);
TextOut(hdc, 200, iY, atcFaceName, _tcslen(atcFaceName));
TextOut(hdc, 600, iY, atcStr, iStrLen);
SelectObject(hdc, hFontOld);
DeleteObject(hFont);
}
EndPaint(hWnd, &ps);
}