WINAPI 如何通过滚动来缩放比例?

问题描述 投票:0回答:0

我有一个带有 x,y 轴的图表,到目前为止只有标记,我需要在用鼠标滚轮滚动时改变图表的比例,下面是我得到的代码,但它只是减少或增加了尺寸窗口,再加上这个功能通过一次。

main.cpp

#include <Windows.h>
#include "FunctionsDefinitions.h"
#include "Common.h"
#include "resource2.h"
#include "graphics.h"

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR args, int nCmdShow)
{
    MainFont = CreateFontA(
        35, 15, 0, 0, FW_MEDIUM,
        FALSE, FALSE, FALSE, DEFAULT_CHARSET,
        OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
        FF_DECORATIVE, "MyFont"
    );

    WNDCLASS MainClass = NewWindowClass((HBRUSH)COLOR_WINDOW, LoadCursor(NULL, IDC_ARROW),
        hInst, LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON1)), L"Main window", MainProcedure);

    if (!RegisterClassW(&MainClass)) 
    {
        MessageBoxA(NULL, "Window registration failed!", "ERROR", MB_ICONEXCLAMATION | MB_OK);
        return ERRORCLASS; 
    }

    MSG MainMessage = { 0 };

    HWND hwnd = CreateWindow(L"Main window", L"Programming 3 Lab", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100,
        WIDTH, HEIGHT, NULL, NULL, NULL, NULL);

    UpdateWindow(hwnd);

    while (GetMessage(&MainMessage, NULL, NULL, NULL))
    {
        TranslateMessage(&MainMessage);
        DispatchMessage(&MainMessage);
    }

    return EXIT_SUCCESS;
}

WNDCLASS NewWindowClass(HBRUSH BgColor, HCURSOR Cursor, HINSTANCE hInst,
    HICON Icon, LPCWSTR Name, WNDPROC Procedure)
{
    WNDCLASS NWC = { 0 };

    NWC.hCursor = Cursor;
    NWC.hIcon = Icon;
    NWC.hbrBackground = BgColor;
    NWC.lpszClassName = Name;
    NWC.lpfnWndProc = Procedure;
    NWC.hInstance = hInst;
    NWC.style = CS_HREDRAW | CS_VREDRAW;

    return NWC;
}

LRESULT CALLBACK MainProcedure(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
    short delta = 0;

    GetClientRect(hwnd, &MainClientRect);
    WidthClientRect = MainClientRect.right;
    HeightClientRect = MainClientRect.bottom;

    switch (msg)
    {
    case WM_COMMAND:
        switch (wp)
        {
        case OnMenuAction1:
            MessageBoxA(hwnd, "Programming 3 lab\nBy Ivan Voitenko KV-24", "About", MB_OK);
            break;

        case OnBtnClicked:
            SendMessage(hButton1, WM_CLOSE, wp, lp);
            SendMessage(hText1, WM_CLOSE, wp, lp);
            OnBtnClickedFlag = true;
            break;

        case OnExitAction:
            PostQuitMessage(EXIT_SUCCESS);
            break;

        default: break;
        }
        break;

    case WM_MOUSEWHEEL:
        delta = GET_WHEEL_DELTA_WPARAM(wp);
        if (delta > 0)
            ZoomIn(hwnd);
        else if (delta < 0)
            ZoomOut(hwnd);

        break;

    case WM_PAINT:
        if (OnBtnClickedFlag == true)
        {
            hdc = BeginPaint(hwnd, &ps);

            FillRect(hdc, &MainClientRect, (HBRUSH)GetStockObject(BLACK_BRUSH));
            DrawMesh(hdc, CurrentScale);

            DrawAxesXY(hdc);

            EndPaint(hwnd, &ps);
        }
        break;

    case WM_CREATE:
        MainWndAddMenu(hwnd);
        MainWndAddWidgets(hwnd);

        SendMessage(hText1, WM_SETFONT, (WPARAM)MainFont, TRUE);
        SendMessage(hButton1, WM_SETFONT, (WPARAM)MainFont, TRUE);
        break;

    case WM_DESTROY:
        PostQuitMessage(EXIT_SUCCESS);
        break;

    default:
        return DefWindowProc(hwnd, msg, wp, lp);
    }
}

void MainWndAddMenu(HWND hwnd)
{
    HMENU RootMenu = CreateMenu();
    HMENU SubMenu = CreateMenu();

    AppendMenu(SubMenu, MF_STRING, OnMenuAction1, L"About");
    AppendMenu(SubMenu, MF_SEPARATOR, NULL, NULL);
    AppendMenu(SubMenu, MF_STRING, OnExitAction, L"Exit");
    
    AppendMenu(RootMenu, MF_POPUP, (UINT_PTR)SubMenu, L"File");

    SetMenu(hwnd, RootMenu);
}

void MainWndAddWidgets(HWND hwnd)
{
    hText1 = CreateWindowA("Static", "PROGRAMMING 3 LAB\nTo continue click button", WS_VISIBLE | WS_CHILD | ES_CENTER, 0, HEIGHT / 2 - 100,
        WIDTH, HEIGHT, hwnd, NULL, NULL, NULL);
    hButton1 = CreateWindowA("Button", "Continue", WS_VISIBLE | WS_CHILD | ES_CENTER, WIDTH / 2 - 105, HEIGHT / 2 - 15,
        220, 60, hwnd, (HMENU)OnBtnClicked, NULL, NULL);
}

void ZoomIn(HWND hwnd)
{
    CurrentScale += 0.1f;

    int new_width = (int)(MainClientRect.right - MainClientRect.left) * CurrentScale;
    int new_height = (int)(MainClientRect.bottom - MainClientRect.top) * CurrentScale;

    SetWindowPos(hwnd, NULL, 0, 0, new_width, new_height, SWP_NOMOVE | SWP_NOZORDER);

    InvalidateRect(hwnd, NULL, TRUE);
}

void ZoomOut(HWND hwnd)
{
    CurrentScale -= 0.1f;

    int new_width = (int)(MainClientRect.right - MainClientRect.left) * CurrentScale;
    int new_height = (int)(MainClientRect.bottom - MainClientRect.top) * CurrentScale;

    SetWindowPos(hwnd, NULL, 0, 0, new_width, new_height, SWP_NOMOVE | SWP_NOZORDER);

    InvalidateRect(hwnd, NULL, TRUE);
}

图形.cpp

#include "Common.h"
#include "graphics.h"

void DrawArrow(HDC hdc)
{
    int ArrowWidth = 10;
    int ArrowHeight = 25;

    HPEN Pen = CreatePen(PS_SOLID, 3, GREEN);
    SelectObject(hdc, Pen);

    MoveToEx(hdc, WidthClientRect / 2, 0, NULL);
    LineTo(hdc, WidthClientRect / 2 - ArrowWidth, ArrowHeight);
    MoveToEx(hdc, WidthClientRect / 2, 0, NULL);
    LineTo(hdc, WidthClientRect / 2 + ArrowWidth, ArrowHeight);

    MoveToEx(hdc, WidthClientRect, HeightClientRect / 2, NULL);
    LineTo(hdc, WidthClientRect - ArrowHeight, HeightClientRect / 2 - ArrowWidth);
    MoveToEx(hdc, WidthClientRect, HeightClientRect / 2, NULL);
    LineTo(hdc, WidthClientRect - ArrowHeight, HeightClientRect / 2 + ArrowWidth);

    DeleteObject(Pen);
}

void DrawMesh(HDC hdc, short scale)
{
    int step = 15 / scale;

    HPEN Pen = CreatePen(PS_SOLID, 1, GREEN);
    SelectObject(hdc, Pen);

    for (int x = 0; x < MainClientRect.right; x += step)
        for (int y = 0; y < MainClientRect.bottom; y += step)
            SetPixel(hdc, x, y, RGB(192, 192, 192));

    DeleteObject(Pen);
}

void DrawAxesXY(HDC hdc)
{
    HPEN Pen = CreatePen(PS_SOLID, 3, GREEN);
    SelectObject(hdc, Pen);
    
    MoveToEx(hdc, 0, HeightClientRect / 2, NULL);
    LineTo(hdc, WidthClientRect, HeightClientRect / 2);
    
    MoveToEx(hdc, WidthClientRect / 2, 0, NULL);
    LineTo(hdc, WidthClientRect / 2, HeightClientRect);

    DeleteObject(Pen);

    DrawArrow(hdc);
}

common.h

#pragma once

#include <Windows.h>
#include <stdbool.h>

#define ERRORCLASS -3
#define WIDTH   1280
#define HEIGHT  960

#define BLACK   RGB(0, 0, 0)
#define RED     RGB(255, 0, 0)
#define WHITE   RGB(255, 255, 255)
#define GREEN   RGB(35, 170, 100)
#define BLUE    RGB(0, 0, 255)
#define CLRMAIN RGB(140, 170, 189)

#define OnMenuAction1   1
#define OnMenuAction2   2

#define OnBtnClicked    3

#define OnExitAction    0

extern unsigned short OnBtnClickedFlag;
extern unsigned short WidthClientRect;
extern unsigned short HeightClientRect;
extern float CurrentScale;

extern HWND hButton1;
extern HWND hText1;
extern HDC hdc;
extern PAINTSTRUCT ps;
extern RECT MainClientRect;
extern HFONT MainFont;

common.cpp

#include "Common.h"

unsigned short OnBtnClickedFlag = false;
unsigned short WidthClientRect = 0;
unsigned short HeightClientRect = 0;
float CurrentScale = 1.0f;

HWND hButton1;
HWND hText1;
HDC hdc;
PAINTSTRUCT ps;
RECT MainClientRect;
HFONT MainFont;

FunctionsDefinitions.h

#pragma once

LRESULT CALLBACK MainProcedure(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp);
WNDCLASS NewWindowClass(HBRUSH BgColor, HCURSOR Cursor, HINSTANCE hInst,
    HICON Icon, LPCWSTR Name, WNDPROC Procedure);

void MainWndAddMenu(HWND hwnd);
void MainWndAddWidgets(HWND hwnd);

void ZoomIn(HWND hwnd);
void ZoomOut(HWND hwnd);
c windows winapi gdi user32
© www.soinside.com 2019 - 2024. All rights reserved.