본문 바로가기

프로그램언어/C++

공용 대화상자 사용하기2

글꼴 대화상자

 

글꼴 함수

BOOL ChooseFont( LPCHOOSEFONT lpcf );

typedef struct {

    DWORD lStructSize;          // 구조체의 크기

    HWND hwndOwner;         // 윈도우 핸들

    HDC hDC;                      //  Flags 필드 값이 CF_PRINTERFONTS또는 CF_BOTH일 때만 의미 있는 필드, 여기선 무시

    LPLOGFONT lpLogFont;    // LOGFONT 구조체 변수의 주소값을 저장하는 곳으로 글꼴대화상자를 통해 선택한 글꼴

    INT iPointSize;                // 선택한 글꼴의 크기를 저장

    DWORD Flags;                // 글꼴 대화상자를 초기화하는 데 사용하는 비트 플래그들의 조합을 저장

    DWORD rgbColors;          // Flags에 CF_EFFECTS가 설정되어 있을 때 의미 있는 필드, 글꼴의 색상 정보를 저장

    LPARAM lCustData;         // 시스템이 lpfnHook 멤버로 식별되는 후크 프로시저로 전달하는 애플리케이션 정의 데이터

    LPCFHOOKPROC lpfnHook;    // 대화상자 용 메시지를 처리 할 수 있는 CFHookProc 후크 프로시저에 대한 포인터
                                 //입니다
. 이 멤버는 CF_ENABLEHOOK 플래그가 Flags 멤버에 설정되어 있지 않으면 무시됩니다 .

    LPCTSTR lpTemplateName;    // hInstance 멤버로 식별되는 모듈에있는 대화 상자 템플릿 리소스의 이름

    HINSTANCE hInstance;       // CF_ENABLETEMPLATEHANDLE 플래그가 Flags 멤버에 설정되어 있으면
                                        // hInstance 는 대화 상자 템플릿을 포함하는 메모리 개체에 대한 핸들

    LPTSTR lpszStyle;              // 글꼴 스타일

    WORD nFontType;            // 선택한 글꼴을 가리키는 필드(굵은 글씨체, 이탤릭체, 일반 글씨체)로 값을지정

    WORD ___MISSING_ALIGNMENT__;

    INT nSizeMin;                 //사용자가 선택할 수있는 최소 포인트 크기

    INT nSizeMax;                // 사용자가 선택할 수있는 최대 포인트 크기    

} CHOOSEFONT;

 

LOGFONT 구조체

typedef struct tagLOGFONT{

    LONG lfHeight; // 문자 셀이나 문자의 논리적 높이

    LONG lfWidth; // 글꼴 내의 문자들의 평균 논리적 너비

    LONG lfEscapement; // 폰트에 쓰여진 텍스트의 각 라인의 각도(1/10)

    LONG lfOrientation; // 각 문자의 기준선의 각도(1/10)

    LONG lfWeight; // 글꼴의 무게(0 ~ 1000 사이)

    BYTE lfItalic; // TRUE 이면 이태릭체. 기울임꼴

    BYTE lfUnderline; // TRUE 이면 밑줄

    BYTE lfStrikeOut; // TRUE 이면 취소선

    BYTE lfCharSet; // 글꼴의 문자 집합

    BYTE lfOutPrecision; // 출력 정밀도

    BYTE lfClipPrecision; // 클리핑 정밀도

    BYTE lfQuality; // 출력 품질

    BYTE lfPitchAndFamily; // 글꼴의 피치와 계열

    CHAR lfFaceName[LF_FACESIZE]; // 글꼴 이름

} LOGFONT

 

LOGFONT 사용 예

CHOOSEFONT FONT;               // CHOOSEFONT 구조체 변수를 선언
LOGFONT LogFont;                 // LOGFONT 구조체 변수 선언
FONT.IStructSize = sizeof(CHOOSEFONT);      // 구조체의 크기
FONT.hwndOwner = hwnd;                        // 윈도우 핸들
FONT.lpLogFont = &LogFont;                    // LogFont의 주소를 저장 (FONT와 LogFont 변수를 서로 연결)
FONT.Flags = CF_EFFECTS | CF_SCREENFONTS;
ChooseFont(&FONT)                                // ChooseFont() 함수 호출
hFont = CreateFontIndirect(&LogFont);           // 글꼴 대화상자에서 글꼴을 선택하면 글꼴 정보가 LOGFONT 에 저장된다.
OldFont = (HFONT)SelectObject(hdc, hFont);    // 이것을 활용해 HFONT를 만들고 디바이스 콘텍스트에 등록하면
                                                             // 사용자가 선택한 글꼴을 사용

 

텍스트 색상 변경 함수

COLORREF SetTextColor(  // 디바이스 콘택스트에 등록된 텍스트 색상 반환
    HDC hdc,               // 변경할 디바이스 컨텍스트
    COLORREF crColor   //변경할 색상
);

 

글꼴 만들기 함수

HFONT CreateFontIndirect(const LOGFONT *lplf);

BOOL CreateFont(

    int nHeight,             // 폰트의 높이

    int nWidth,             //폰트의 가로크기

    int nEscapement,      // escapement 벡터각도

    int nOrientation,       // 기준선(보통 수평선) 에서의 각도

    int fnWeight,           // 폰트 가중치

    DWORD fdwItalic,     // 이탤릭 속성 플러그

    DWORD fdwUnderline,           // 밑줄 속성 플러그

    DWORD fdwStrikeOut,           // 중앙선 속성 플러그

    DWORD fdwCharSet,             // 문자열 세트 명칭

    DWORD fdwOutputPrecision,  // 출력 정밀도

    DWORD fdwClipprecision,      // 클리핑 정밀도

    DWORD fdwQuality,             // 출력 문자의 질

    DWORD fdwPitchAndFamily,   // 글꼴 피치의 종류

    LPCSTR lpszFace                  // 폰트체의 이름

);

 

글꼴 대화상자

#include <windows.h>

#include <TCHAR.H>

#include "resource.h"

 

LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)

{

    HWND hwnd;

    MSG msg;

    WNDCLASS WndClass;

    WndClass.style = CS_HREDRAW | CS_VREDRAW

    WndClass.lpfnWndProc = WndProc;

    WndClass.cbClsExtra = 0;

    WndClass.cbWndExtra = 0;

    WndClass.hInstance = hInstance

    WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);

    WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);

    WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);

    WndClass.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);

    WndClass.lpszClassName = _T("Window Class Name");

    RegisterClass(&WndClass);

    hwnd = CreateWindow(_T("Window Class Name"), _T("Window Title Name"), WS_OVERLAPPEDWINDOW,

               CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL );

    ShowWindow(hwnd, nCmdShow);

    UpdateWindow(hwnd);

    while (GetMessage(&msg, NULL, 0, 0))

    {

        TranslateMessage(&msg);

        DispatchMessage(&msg);

    }

    return (int)msg.wParam;

}

void OutFromFile(TCHAR filename[], HWND hwnd)

{

    FILE *fPtr;

    HDC hdc;

    int line;

    TCHAR buffer[500];

    line = 0;

    hdc = GetDC(hwnd);

#ifdef _UNICODE

    _tfopen_s(&fPtr, filename, _T("r, ccs = UNICODE"));

#else

    _tfopen_s(&fPtr, filename, _T("r"));

#endif

    while (_fgetts(buffer, 100, fPtr) != NULL)

    {

        if (buffer[_tcslen(buffer) - 1] == _T('\n'))

            buffer[_tcslen(buffer) - 1] = NULL;

        TextOut(hdc, 0, line * 20, buffer, _tcslen(buffer));

        line++;

    }

    fclose(fPtr);

    ReleaseDC(hwnd, hdc);

}

LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)

{

    HDC hdc;

    PAINTSTRUCT ps;

    CHOOSEFONT FONT;

    static COLORREF fColor;

    HFONT hFont, OldFont;

    static LOGFONT LogFont;

 

    OPENFILENAME OFN;

    OPENFILENAME OFN;

    TCHAR lpstrFile[100] = _T("");

    TCHAR filter[] = _T("Every File(*.*) \0*.*\0")

                          _T("Text File\0*.txt;*.doc\0");

    switch (iMsg)

    {

    case WM_CREATE:

        break;

    case WM_COMMAND:

        switch (LOWORD(wParam))

        {

        case ID_FILESAVE:

            memset(&SFN, 0, sizeof(OPENFILENAME));

            SFN.lStructSize = sizeof(OPENFILENAME);

            SFN.hwndOwner = hwnd;

            SFN.lpstrFilter = filter;

            SFN.lpstrFile = lpstrFile;

            SFN.nMaxFile = 256;

            SFN.lpstrInitialDir = _T(".");

            if (GetSaveFileName(&SFN) != 0)

            {

                _stprintf_s(str, _T("%s 파일로저장하겠습니까), SFN.lpstrFile);

                MessageBox(hwnd, str, _T("저장하기선택"), MB_OK);

            }

            break;

        case ID_FILEOPEN:

            memset(&OFN, 0, sizeof(OPENFILENAME));

            OFN.lStructSize = sizeof(OPENFILENAME);

            OFN.hwndOwner = hwnd;

            OFN.lpstrFilter = filter;

            OFN.lpstrFile = lpstrFile;

            OFN.nMaxFile = 256;

            OFN.lpstrInitialDir = _T(".");

            if (GetOpenFileName(&OFN) != 0)

                OutFromFile(OFN.lpstrFile, hwnd);

                break;

        case ID_FONTDLG:

            memset(&FONT, 0, sizeof(CHOOSEFONT));

            FONT.lStructSize = sizeof(CHOOSEFONT);

            FONT.hwndOwner = hwnd;

            FONT.lpLogFont = &LogFont;
// CF_EFFECTS : 사용자가 취소 선, 밑줄 및 텍스트 색상 옵션을 지정할 수있는 컨트롤을 대화 상자에 표시합니다. 
// 이 플래그가 설정되면 rgbColors 멤버를 사용하여 초기 텍스트 색상을 지정할 수 있습니다
// CF_SCREENFONTS : 글꼴 열거에서는이 플래그가 무시됩니다.

// Windows Vista 및 Windows XP / 2000 :   대화 상자에 시스템에서 지원하는 화면 글꼴 만 나열됩니다.

            FONT.Flags = CF_EFFECTS | CF_SCREENFONTS;

            if (ChooseFont(&FONT) != 0)

            {

                fColor = FONT.rgbColors;

                InvalidateRgn(hwnd, NULL, TRUE);

            }

            break;

        }

        break;
    case WM_PAINT:
        hdc = BeginPaint(hwnd, &ps);
// CreateFontIndirect(&LogFont) : LOGFONT 구조체는 CreateFont 함수의 인수 전체를 멤버 변수로 가지는 구조체이며
// 이 구조체에 원하는 값을 먼저 대입한 후 CreateFontIndirect 함수로 이 구조체의 번지를 넘겨줌

        hFont = CreateFontIndirect(&LogFont);
        OldFont = (HFONT)SelectObject(hdc, hFont);
        SetTextColor(hdc, fColor);
        TextOut(hdc, 10, 10, _T("HelloWorld"), 10);
        SelectObject(hdc, OldFont);
        DeleteObject(hFont);
        EndPaint(hwnd, &ps);
        break;

    case WM_DESTROY:

        PostQuitMessage(0);

        break;

    }

    return DefWindowProc(hwnd, iMsg, wParam, lParam);

}

실행 결과]

 

색 대화상자

 

CHOOSECOLOR 구조체

typedef struct {

    DWORD lStructSize;      // 구조체의 크기

    HWND hwndOwner;     // 대화상자를 띄우는 부모 윈도우 핸들

    HWND hInstance;        // hInstance 대화 상자 템플릿에 포함 된 메모리 개체의 핸들

    COLORREF rgbResult;   // 색 대화상자에서 선택한 색상 정보를 저장

    COLORREF * lpCustColors;    // 색 대화상자의 사용자가 지정 색을 채울 색 정보 목록

    DWORD Flags;          // 색 대화상자를 초기화하는 데 사용하는 비트 플래그의 조합,  

    LPARAM lCustData;    // 시스템 lpfnHook 구성원에 의해 식별 된 후크 프로시저에 전달 하는 응용 프로그램 정의
                                 // 데이터를 지정

    LPCCHOOKPROC lpfnHook;   // CCHookProc 에 대 한 포인터 후크 프로시저 대화 상자를 위한 메시지를 처리

    LPCTSTR lpTemplateName;   // HInstance 회원에 의해 식별 된 모듈에서 대화 상자 템플릿 리소스 이름이
                                          //
null로 끝나는 문자열 포인터

} *LPCHOOSECOLOR

 

색 대화상자

LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)

{

   HDC hdc;

    PAINTSTRUCT ps;

    CHOOSEFONT FONT;

    static COLORREF fColor;

    HFONT hFont, OldFont;

    static LOGFONT LogFont;

    CHOOSECOLOR COLOR;

    static COLORREF tmp[16], color;

    HBRUSH hBrush, OldBrush;

    int i;

 

    OPENFILENAME OFN;

    OPENFILENAME OFN;

    TCHAR lpstrFile[100] = _T("");

    TCHAR filter[] = _T("Every File(*.*) \0*.*\0")

                          _T("Text File\0*.txt;*.doc\0");

    switch (iMsg)

    {

    case WM_CREATE:

        break;

    case WM_COMMAND:

        switch (LOWORD(wParam))

        {

        case ID_FILESAVE:

            memset(&SFN, 0, sizeof(OPENFILENAME));

            SFN.lStructSize = sizeof(OPENFILENAME);

            SFN.hwndOwner = hwnd;

            SFN.lpstrFilter = filter;

            SFN.lpstrFile = lpstrFile;

            SFN.nMaxFile = 256;

            SFN.lpstrInitialDir = _T(".");

            if (GetSaveFileName(&SFN) != 0)

            {

                _stprintf_s(str, _T("%s 파일로저장하겠습니까), SFN.lpstrFile);

                MessageBox(hwnd, str, _T("저장하기선택"), MB_OK);

            }

            break;

        case ID_FILEOPEN:

            memset(&OFN, 0, sizeof(OPENFILENAME));

            OFN.lStructSize = sizeof(OPENFILENAME);

            OFN.hwndOwner = hwnd;

            OFN.lpstrFilter = filter;

            OFN.lpstrFile = lpstrFile;

            OFN.nMaxFile = 256;

            OFN.lpstrInitialDir = _T(".");

            if (GetOpenFileName(&OFN) != 0)

                OutFromFile(OFN.lpstrFile, hwnd);

                break;

       case ID_FONTDLG:

            memset(&FONT, 0, sizeof(CHOOSEFONT));

            FONT.lStructSize = sizeof(CHOOSEFONT);

            FONT.hwndOwner = hwnd;

            FONT.lpLogFont = &LogFont;

            FONT.Flags = CF_EFFECTS | CF_SCREENFONTS;

            if (ChooseFont(&FONT) != 0)

            {

                fColor = FONT.rgbColors;

                InvalidateRgn(hwnd, NULL, TRUE);

            }

            break;

        case ID_COLORDLG:

            for (i = 0; i<16; i++)

                tmp[i] = RGB(rand() % 256, rand() % 256, rand() % 256);

            memset(&COLOR, 0, sizeof(CHOOSECOLOR));

            COLOR.lStructSize = sizeof(CHOOSECOLOR);

            COLOR.hwndOwner = hwnd;

            COLOR.lpCustColors = tmp;
// CC_FULLOPEN : 사용자가 사용자 지정 색을 만들 수있는 추가 컨트롤을 대화 상자에 표시

            COLOR.Flags = CC_FULLOPEN;

            if (ChooseColor(&COLOR) != 0)

            {

                color = COLOR.rgbResult;

                InvalidateRgn(hwnd, NULL, TRUE);

            }

            break;

        }

        break;
    case WM_PAINT: 
        hdc = BeginPaint(hwnd, &ps); 
        /* 글꼴 변경
        hFont = CreateFontIndirect(&LogFont); 
        OldFont = (HFONT)SelectObject(hdc, hFont); 
        SetTextColor(hdc, fColor); 
        TextOut(hdc, 10, 10, _T("HelloWorld"), 10); 
        SelectObject(hdc, OldFont); 
        DeleteObject(hFont);
        */

        hBrush = CreateSolidBrush(color);

        OldBrush = (HBRUSH)SelectObject(hdc, hBrush);

        Ellipse(hdc, 10, 10, 200, 200);

        SelectObject(hdc, OldBrush);

        DeleteObject(hBrush);
        EndPaint(hwnd, &ps); 
        break;

    case WM_DESTROY:

        PostQuitMessage(0);

        break;

    }

    return DefWindowProc(hwnd, iMsg, wParam, lParam);

}

실행 결과]

 

메뉴수정하기 ( 메뉴 활성화와 비활성화 )

 

메뉴 관련 함수

설정된 메뉴 불러오기
HMENU GetMenu(HWND hWnd);

부메뉴 불러오기
HMENU GetSubMenu(HMENU hMenu, int nPos);

메뉴 항목 활성화, 비활성화
BOOL EnableMenuItem(HMENU hMenu,
            INT uIDEnableItem,    // 활성화, 비활성화 또는 회색으로 표시되는 메뉴 항목
            UINT uEnable           // 비활성화 : MF_GRAYED, 활성화 : MF_ENABLED
);

 

복사하기, 붙여넣기 메뉴 항목 비활성화하기

LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)

{
    // ... 중간생략 ... 

    static HMENU hMenu, hSubMenu;

    // ... 중간생략 ... 

    switch (iMsg)

    {

    case WM_CREATE:

        hMenu = GetMenu(hwnd);

        hSubMenu = GetSubMenu(hMenu, 1);

        EnableMenuItem(hSubMenu, ID_EDITCOPY, MF_GRAYED);

        EnableMenuItem(hSubMenu, ID_EDITPASTE, MF_GRAYED);

        break;

    case WM_COMMAND:
         // ... 중간생략 ... 

    }

    return DefWindowProc(hwnd, iMsg, wParam, lParam);

}

실행 결과]

 

객체를 선택 후 복사하기, 붙여넣기 메뉴 항목 활성화하기

#include <math.h>
#define BSIZE 40
double LengthPts(int x1, int y1, int x2, int y2)
{
    return(sqrt((float)((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1))));
}

BOOL InCircle(int x, int y, int mx, int my)
{
    if (LengthPts(x, y, mx, my) < BSIZE)
        return TRUE;
    else
        return FALSE;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)

{

    // ... 중간 생략 ...

    static HMENU hMenu, hSubMenu;

    int mx, my;

    static BOOL Select;

    static BOOL Copy;

    static int x, y;
    // ... 중간 생략 ...

    switch (iMsg)

    {

    case WM_CREATE:

        hMenu = GetMenu(hwnd);

        hSubMenu = GetSubMenu(hMenu, 1);

        Select = FALSE;

        Copy = FALSE;

        x = 50; y = 50;

        break;

    case WM_LBUTTONDOWN:

        mx = LOWORD(lParam);

        my = HIWORD(lParam);

        if (InCircle(x, y, mx, my))
            Select = TRUE

        InvalidateRgn(hwnd, NULL, TRUE);

        break;

    case WM_COMMAND:

        switch (LOWORD(wParam))

        {

        case ID_EDITCOPY:

            Copy = TRUE;

            InvalidateRgn(hwnd, NULL, TRUE);

            break;
        // ... 중간 생략 ....
    case WM_PAINT:
        EnableMenuItem(hSubMenu, ID_EDITCOPY, Select ? MF_ENABLED : MF_GRAYED);
        EnableMenuItem(hSubMenu, ID_EDITPASTE, Copy ? MF_ENABLED : MF_GRAYED);
        hdc = BeginPaint(hwnd, &ps);
        // ... 중간 생략 ...
        if (Select)
            Rectangle(hdc, x - BSIZE, y - BSIZE, x + BSIZE, y + BSIZE);
            Ellipse(hdc, x - BSIZE, y - BSIZE, x + BSIZE, y + BSIZE);
        EndPaint(hwnd, &ps);
        break;

        // ... 중간생략 ...

실행 결과]

 

'프로그램언어 > C++' 카테고리의 다른 글

API 비트맵  (0) 2020.09.28
API 단축키  (0) 2020.09.28
API 공용 대화상자 사용1  (0) 2020.09.25
API 리소스  (0) 2020.09.23
API 그리기 모드(Draw Mode)  (0) 2020.09.23