Win32 Api 学习记录-Ocrosoft
浙江财经大学
信工学院ACM集训队

Win32 Api 学习记录

本文由 Ocrosoft 于 2018-05-12 23:24:36 发表

摘要:使用子窗体绘制两个自绘按钮,用来缩放窗口

1.1.源码

#include <windows.h>

#define ID_SMALLER 1
#define ID_LARGER 2
#define BTN_WIDTH (8 * cxChar)
#define BTN_HEIGHT (4 * cyChar)

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

HINSTANCE hInst;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
    static TCHAR szAppName[] = TEXT("OwnDraw");
    MSG msg;
    HWND hwnd;
    WNDCLASS wndclass;

    hInstance = hInstance;

    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(GRAY_BRUSH);
    wndclass.lpszMenuName = szAppName;
    wndclass.lpszClassName = szAppName;

    if (!RegisterClass(&wndclass))
    {
        MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);
        return 0;
    }

    hwnd = CreateWindow(szAppName, TEXT("Owner-Draw Button Demo"), WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
                        NULL, NULL, hInstance, NULL);
    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);

    while(GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

void Triangle(HDC hdc, POINT pt[]) // 绘制三角
{
    SelectObject(hdc, GetStockObject(BLACK_BRUSH));
    Polygon(hdc, pt, 3);
    SelectObject(hdc, GetStockObject(WHITE_BRUSH));
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static HWND hwndSmaller, hwndLarger; // 两个子窗口句柄
    static int cxClient, cyClient, cxChar, cyChar;
    int cx, cy;
    LPDRAWITEMSTRUCT pdis;
    POINT pt[3];
    RECT rc;

    switch(message)
    {
    case WM_CREATE:
        cxChar = LOWORD(GetDialogBaseUnits());
        cyChar = HIWORD(GetDialogBaseUnits());

        hwndSmaller = CreateWindow(TEXT("button"), TEXT(""),
                                   WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,
                                   0, 0, BTN_WIDTH, BTN_HEIGHT,
                                   hwnd, (HMENU)ID_SMALLER, hInst, NULL);

        hwndLarger = CreateWindow(TEXT("button"), TEXT(""),
                                  WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,
                                  0, 0, BTN_WIDTH, BTN_HEIGHT,
                                  hwnd, (HMENU)ID_LARGER, hInst, NULL);
        return 0;

    case WM_SIZE:
        cxClient = LOWORD(lParam);
        cyClient = HIWORD(lParam);

        MoveWindow(hwndSmaller, cxClient / 2 - 3 * BTN_WIDTH / 2,
                   cyClient / 2 - BTN_HEIGHT / 2,
                   BTN_WIDTH, BTN_HEIGHT, TRUE); // 调整两个按钮的位置并显示

        MoveWindow(hwndLarger, cxClient / 2 + BTN_WIDTH / 2,
                   cyClient / 2 - BTN_HEIGHT / 2,
                   BTN_WIDTH, BTN_HEIGHT, TRUE);
        return 0;

    case WM_COMMAND:
        GetWindowRect(hwnd, &rc); // 获取整个窗口的矩形区域(不只是客户区

        switch(wParam) // 根据按下的按钮调整矩形大小
        {
        case ID_SMALLER:
            rc.left += cxClient / 20;
            rc.right -= cxClient / 20;
            rc.top += cyClient / 20;
            rc.bottom -= cyClient / 20;
            break;

        case ID_LARGER:
            rc.left -= cxClient / 20;
            rc.right += cxClient / 20;
            rc.top -= cyClient / 20;
            rc.bottom += cyClient / 20;
            break;
        }

        MoveWindow(hwnd, rc.left, rc.top, rc.right - rc.left,
                   rc.bottom - rc.top, TRUE); // 移动窗口位置、调整窗口大小,会触发WM_SIZE
        return 0;

    case WM_DRAWITEM:
        pdis = (LPDRAWITEMSTRUCT)lParam;

        FillRect(pdis->hDC, &pdis->rcItem, // 填充白色
                 (HBRUSH)GetStockObject(WHITE_BRUSH));
        FrameRect(pdis->hDC, &pdis->rcItem, // 画边框
                  (HBRUSH)GetStockObject(BLACK_BRUSH));

        cx = pdis->rcItem.right - pdis->rcItem.left;
        cy = pdis->rcItem.bottom - pdis->rcItem.top;

        switch(pdis->CtlID) // 绘制三角
        {
        case ID_SMALLER:
            pt[0].x = 3 * cx / 8;
            pt[0].y = 1 * cy / 8;
            pt[1].x = 5 * cx / 8;
            pt[1].y = 1 * cy / 8;
            pt[2].x = 4 * cx / 8;
            pt[2].y = 3 * cy / 8;

            Triangle(pdis->hDC, pt);

            pt[0].x = 7 * cx / 8;
            pt[0].y = 3 * cy / 8;
            pt[1].x = 7 * cx / 8;
            pt[1].y = 5 * cy / 8;
            pt[2].x = 5 * cx / 8;
            pt[2].y = 4 * cy / 8;

            Triangle(pdis->hDC, pt);

            pt[0].x = 5 * cx / 8;
            pt[0].y = 7 * cy / 8;
            pt[1].x = 3 * cx / 8;
            pt[1].y = 7 * cy / 8;
            pt[2].x = 4 * cx / 8;
            pt[2].y = 5 * cy / 8;

            Triangle(pdis->hDC, pt);

            pt[0].x = 1 * cx / 8;
            pt[0].y = 5 * cy / 8;
            pt[1].x = 1 * cx / 8;
            pt[1].y = 3 * cy / 8;
            pt[2].x = 3 * cx / 8;
            pt[2].y = 4 * cy / 8;

            Triangle(pdis->hDC, pt);
            break;

        case ID_LARGER:
            pt[0].x = 5 * cx / 8;
            pt[0].y = 3 * cy / 8;
            pt[1].x = 3 * cx / 8;
            pt[1].y = 3 * cy / 8;
            pt[2].x = 4 * cx / 8;
            pt[2].y = 1 * cy / 8;

            Triangle(pdis->hDC, pt);

            pt[0].x = 5 * cx / 8;
            pt[0].y = 5 * cy / 8;
            pt[1].x = 5 * cx / 8;
            pt[1].y = 3 * cy / 8;
            pt[2].x = 7 * cx / 8;
            pt[2].y = 4 * cy / 8;

            Triangle(pdis->hDC, pt);

            pt[0].x = 3 * cx / 8;
            pt[0].y = 5 * cy / 8;
            pt[1].x = 5 * cx / 8;
            pt[1].y = 5 * cy / 8;
            pt[2].x = 4 * cx / 8;
            pt[2].y = 7 * cy / 8;

            Triangle(pdis->hDC, pt);

            pt[0].x = 3 * cx / 8;
            pt[0].y = 3 * cy / 8;
            pt[1].x = 3 * cx / 8;
            pt[1].y = 5 * cy / 8;
            pt[2].x = 1 * cx / 8;
            pt[2].y = 4 * cy / 8;

            Triangle(pdis->hDC, pt);
            break;
        }

        if (pdis->itemState & ODS_SELECTED)
            InvertRect(pdis->hDC, &pdis->rcItem); // 像素翻转(反相)

        if (pdis->itemState & ODS_FOCUS) // 有焦点,绘制焦点虚线框
        {
            pdis->rcItem.left += cx / 16;
            pdis->rcItem.top += cy / 16;
            pdis->rcItem.right -= cx / 16;
            pdis->rcItem.bottom -= cx / 16;

            DrawFocusRect(pdis->hDC, &pdis->rcItem);
        }
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

欢迎转载,请保留出处与链接。Ocrosoft » Win32 Api 学习记录

点赞 (0)or拍砖 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址