본문 바로가기

Windows/Windows API

[self] 내가만든 폰트 뷰어 (메세지크랙커방식)

#include <windows.h>

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
HWND hWndMain;
LPSTR lpszClass="FontViewer";

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance
         ,LPSTR lpszCmdParam,int nCmdShow)
{
    HWND hWnd;
    MSG Message;
    WNDCLASS WndClass;
    g_hInst=hInstance;
    
    WndClass.cbClsExtra=0;
    WndClass.cbWndExtra=0;
    WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
    WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
    WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    WndClass.hInstance=hInstance;
    WndClass.lpfnWndProc=(WNDPROC)WndProc;
    WndClass.lpszClassName=lpszClass;
    WndClass.lpszMenuName=NULL;
    WndClass.style=CS_HREDRAW | CS_VREDRAW ;
    RegisterClass(&WndClass);

    hWnd=CreateWindow(lpszClass,lpszClass, WS_OVERLAPPEDWINDOW | WS_MAXIMIZE,
        CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
        NULL,(HMENU)NULL,hInstance,NULL);
    ShowWindow(hWnd,nCmdShow);
    hWndMain=hWnd;
    
    while(GetMessage(&Message,0,0,0)) {
        TranslateMessage(&Message);
        DispatchMessage(&Message);
    }
    return Message.wParam;
}



#include <windowsx.h>

#define ID_EDIT 100
#define ID_LIST 101
#define ID_R1    102
#define ID_R2    103
#define ID_R3    104
#define ID_R4    105
#define IDC_CB_CHANGE 106
#define MAXFONT 1500

HWND hList, hEdit,r1,r2,r3,r4, hCbChange;
char lpstrOutString[][50] = {
    {"ABCDEFGHIJKLMNOPQRSTUVWXYZ"},
    {"abcdefghijklmnopqrstuvwxyz"},
    {"가나다라마바사아자차카타파하"},
};
char lpstrEditString[50];
char lpstrCntFont[30];

LOGFONT logfont[MAXFONT];            // 폰트 정보 배열
short num=0, iStringIdx=0;            // 발견된 폰트 수
HFONT hFontEdit;
char szSize[20];
int iFontSize = 20;

// 발견된 폰트의 정보를 배열에 복사한다.
int CALLBACK EnumFamCallBack(ENUMLOGFONT FAR *lpelf, NEWTEXTMETRIC FAR *lpntm,
                             int FontType, LPARAM lParam)
{
    if (num < MAXFONT) {
        logfont[num] = lpelf->elfLogFont;
        num++;
        return TRUE;
    }
    else {
        return FALSE;
    }
}

BOOL OnCreate(HWND, LPCREATESTRUCT);
void OnDestroy(HWND);
void OnPaint(HWND);
void OnCommand(HWND, int, HWND, UINT);
BOOL OnMeasureitem(HWND, MEASUREITEMSTRUCT *);
void OnDrawitem(HWND, const DRAWITEMSTRUCT *);
void OnSize(HWND, UINT, int, int);

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
    switch(iMessage) {
        HANDLE_MSG(hWnd, WM_CREATE,            OnCreate);
        HANDLE_MSG(hWnd, WM_DESTROY,        OnDestroy);
        HANDLE_MSG(hWnd, WM_COMMAND,        OnCommand);
        HANDLE_MSG(hWnd, WM_MEASUREITEM,    OnMeasureitem);
        HANDLE_MSG(hWnd, WM_DRAWITEM,        OnDrawitem);
        HANDLE_MSG(hWnd, WM_PAINT,            OnPaint);
        HANDLE_MSG(hWnd, WM_SIZE,            OnSize);
    }
    return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}


BOOL OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct)
{
    int i;
    HDC hdc;

    // 오너 드로우 콤보 박스 생성
    hList=CreateWindow("listbox",NULL,WS_CHILD | WS_VISIBLE | WS_BORDER
        | WS_VSCROLL | WS_HSCROLL | LBS_OWNERDRAWFIXED,
        220,10,400,400,hWnd,(HMENU)ID_LIST,g_hInst,NULL);

    hEdit=CreateWindow("edit", lpstrOutString[iStringIdx],WS_CHILD | WS_VISIBLE | WS_BORDER |
        ES_AUTOHSCROLL,10,10,200,25,hWnd,(HMENU)ID_EDIT,g_hInst,NULL);

    hFontEdit=CreateFont(12,0,0,0,0,0,0,0,HANGEUL_CHARSET,3,2,1,VARIABLE_PITCH | FF_ROMAN,"굴림");
    SendMessage(hEdit, WM_SETFONT, (WPARAM)hFontEdit, MAKELPARAM(FALSE,0));
    SendMessage(hWnd, WM_SETFONT, (WPARAM)hFontEdit, MAKELPARAM(FALSE,0));

    r1=CreateWindow("button","ABC..",WS_CHILD | WS_VISIBLE |
        BS_AUTORADIOBUTTON | WS_GROUP,
        10,60,100,30,hWnd,(HMENU)ID_R1,g_hInst,NULL);
    r2=CreateWindow("button","abc..",WS_CHILD | WS_VISIBLE |
        BS_AUTORADIOBUTTON,
        10,90,100,30,hWnd,(HMENU)ID_R2,g_hInst,NULL);
    r3=CreateWindow("button","가나다..",WS_CHILD | WS_VISIBLE |
        BS_AUTORADIOBUTTON,
        10,120,100,30,hWnd,(HMENU)ID_R3,g_hInst,NULL);

    SendMessage(r1, WM_SETFONT, (WPARAM)hFontEdit, MAKELPARAM(FALSE,0));
    SendMessage(r2, WM_SETFONT, (WPARAM)hFontEdit, MAKELPARAM(FALSE,0));
    SendMessage(r3, WM_SETFONT, (WPARAM)hFontEdit, MAKELPARAM(FALSE,0));

    hCbChange=CreateWindow("combobox", "12pt",WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_VSCROLL ,
        120,60,90,90,hWnd,(HMENU)IDC_CB_CHANGE,g_hInst,NULL);
    
    SendMessage(hCbChange, WM_SETFONT, (WPARAM)hFontEdit, MAKELPARAM(FALSE,0));
    for (i=10;i<51;i++) {
        wsprintf(szSize,"%dpt",i);
        SendMessage(hCbChange, CB_ADDSTRING, 0, (LPARAM)szSize);
    }

    // 설치되어 있는 폰트의 목록을 조사한다.
    hdc=GetDC(hWnd);
    EnumFontFamilies(hdc, NULL, (FONTENUMPROC)EnumFamCallBack, (LPARAM)NULL);
    ReleaseDC(hWnd, hdc);

    SendMessage(hList, LB_RESETCONTENT,0,0);
    for (i=0;i<num;i++) {
        SendMessage(hList, LB_ADDSTRING, 0, (LPARAM)&logfont[i]);
    }
    strcpy(lpstrEditString, lpstrOutString[0]);

    return TRUE;
}

void OnDestroy(HWND hWnd)
{
    PostQuitMessage(0);
}

void OnPaint(HWND hWnd)
{
    HDC hdc;
    PAINTSTRUCT ps;

    hdc=BeginPaint(hWnd, &ps);
    wsprintf(lpstrCntFont, "전체 폰트 수 : %d개", num);
    TextOut(hdc,10,160,lpstrCntFont,strlen(lpstrCntFont));
    EndPaint(hWnd, &ps);
}

// hWnd, L(wParam), (hwnd)lParam, H(wParam)
void OnCommand(HWND hWnd, int id, HWND hwndCtl, UINT nFlags)
{
    int i;

    switch (id) {
    case ID_EDIT:
        switch (nFlags) {
        case EN_CHANGE:
            GetWindowText(hEdit,lpstrEditString,100);
            InvalidateRect(hWnd,NULL,TRUE);
            break;
        }
        break;
    case ID_R1:
        strcpy(lpstrEditString, lpstrOutString[0]);
        SetWindowText(hEdit,lpstrEditString);
        InvalidateRect(hWnd,NULL,TRUE);
        break;
    case ID_R2:
        strcpy(lpstrEditString, lpstrOutString[1]);
        SetWindowText(hEdit,lpstrEditString);
        InvalidateRect(hWnd,NULL,TRUE);
        break;
    case ID_R3:
        strcpy(lpstrEditString, lpstrOutString[2]);
        SetWindowText(hEdit,lpstrEditString);
        InvalidateRect(hWnd,NULL,TRUE);
        break;    
    case IDC_CB_CHANGE:
        switch (nFlags) {
        case CBN_SELCHANGE:
            i = SendMessage(hCbChange, CB_GETCURSEL, 0, 0);
            iFontSize = i + 10;
            InvalidateRect(hWnd,NULL,TRUE);
            break;
        }
        break;
    }
}

BOOL OnMeasureitem(HWND hWnd, MEASUREITEMSTRUCT* lpMeasureItem)
{
    lpMeasureItem->CtlType = ODT_LISTBOX;
    lpMeasureItem->itemHeight = iFontSize+5;

    return TRUE;
}

void OnDrawitem(HWND hWnd, const DRAWITEMSTRUCT *lpDrawItem)
{
    HBRUSH bkBrush;
    LOGFONT tmpFont;
    HFONT font, oldfont;


//    lpDrawItem->CtlType = ODT_LISTBOX;

    // 선택된 항목은 파란 배경에 흰색으로 출력한다.
    if (lpDrawItem->itemState & ODS_SELECTED) {
        bkBrush=CreateSolidBrush(RGB(0,0,255));
        SetBkColor(lpDrawItem->hDC, RGB(0,0,255));
        SetTextColor(lpDrawItem->hDC, RGB(255,255,255));
    }
    else {
        bkBrush=CreateSolidBrush(RGB(255,255,255));
        SetBkColor(lpDrawItem->hDC, RGB(255,255,255));
        SetTextColor(lpDrawItem->hDC, RGB(0,0,0));
    }
    FillRect(lpDrawItem->hDC, &lpDrawItem->rcItem, bkBrush);
    DeleteObject(bkBrush);

    // 25 픽셀 높이로 글꼴 이름을 출력한다.
    tmpFont=logfont[lpDrawItem->itemID];
    tmpFont.lfHeight=iFontSize;
    tmpFont.lfWidth=0;
    font=CreateFontIndirect(&tmpFont);
    oldfont=(HFONT)SelectObject(lpDrawItem->hDC,font);

    //TextOut(lpDrawItem->hDC,lpDrawItem->rcItem.left+5, lpDrawItem->rcItem.top+2, logfont[lpDrawItem->itemID].lfFaceName, strlen(logfont[lpDrawItem->itemID].lfFaceName));
    TextOut(lpDrawItem->hDC,lpDrawItem->rcItem.left+5, lpDrawItem->rcItem.top+2, lpstrEditString, strlen(lpstrEditString));
    SelectObject(lpDrawItem->hDC,oldfont);
    DeleteObject(font);
}

// hWnd, wParam, L(lParam), H(lParam)
void OnSize(HWND hWnd, UINT state, int cx, int cy)
{
    RECT crt;

    GetClientRect(hWnd, &crt);
    MoveWindow(hList, 220, 10, crt.right-230, crt.bottom-10, TRUE);
}

'Windows > Windows API' 카테고리의 다른 글

에디트 메세지 (edit box messages)  (0) 2013.10.01
에디트 스타일 (edit style)  (0) 2013.10.01
메세지 크랙커  (0) 2013.10.01
서브 클래싱  (0) 2013.10.01
폰트 출력 콤보박스  (0) 2013.10.01