首页 新闻 会员 周边

这个程序加断点能运行,不加断点结果不是我想要的。

0
悬赏园豆:100 [待解决问题]

主要问题是我想让滚动条点到静态文本区时不闪烁,所以用Enablewindow把两个滚动条先设置为FALSE后设置为TRUE,结果这么一跑后续想读取滚轮信息让图片缩放的功能失效了,但是加断点或者先点一下按钮这种控件又能跑了,这是什么原因,或者能让滚动条不闪烁的方法是什么。

include<Windows.h>

include<stdio.h>

define IDS_PAINTREGION 101

define IDB_INPUT 102

define IDB_COUNT 103

define IDS_BEGINPLACE 104

define IDS_ENDPLACE 105

HWND staPaint;
HWND btnInput;
HWND btnCount;
HWND staBegin;
HWND staEnd;
HWND scrVertical;
HWND scrHorizontal;

HBITMAP bmpImage;

int horizontalMax;
int verticalMax;
int horizontalNow = 0;;
int verticalNow = 0;;

double imageProportion = 1.0;

// 初始化窗口先注册,后创建
// 注册用WNDCLASSEx,RegisterClassEx,注册时要回调函数
// 创建用CreateWindowEx

enum class ResponseComponent
{
none = 0,
verticalscrollbar = 1,
horizontalscrollbar = 2,
paintregion = 3
};
ResponseComponent responsecomponent = ResponseComponent::none;

class Vec2
{
public:
double x, y;
Vec2() :x(0), y(0) {}
Vec2(double xx, double yy) :x(xx), y(yy) {};
Vec2 operator+(Vec2 num)
{
return Vec2(x + num.x, y + num.y);
}
Vec2 operator-(Vec2 num)
{
return Vec2(x - num.x, y - num.y);
}
Vec2 operator/(double num)
{
return Vec2(x / num, y / num);
}
Vec2 operator*(double num)
{
return Vec2(x * num, y * num);
}
};

class Rect
{
public:
Rect() :size(), position() {}
Rect(Vec2 position, Vec2 size) :size(size), position(position) {}
Vec2 size;
Vec2 position;
bool isInRect(Vec2 point)
{
Vec2 left_top = position - size / 2.0;
Vec2 right_buttom = position + size / 2.0;
if (point.x >= left_top.x && point.y >= left_top.y &&
point.x <= right_buttom.x && point.y <= right_buttom.y)return true;
return false;
}
Vec2 GetLeftTop()
{
return position - size / 2.0;
}
Vec2 GetRightDown()
{
return position + size / 2.0;
}
};

LRESULT __stdcall CallBackFunc_Main(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

bool RegisterWindow(HINSTANCE hinstance, const TCHAR* classname, COLORREF background,
LRESULT(*callbackfunc)(HWND, UINT, WPARAM, LPARAM))
{
// 一共12个值需要初始化
WNDCLASSEX wndcl;
wndcl.cbSize = sizeof(WNDCLASSEX);
wndcl.lpfnWndProc = callbackfunc;
wndcl.hInstance = hinstance;
wndcl.hCursor = LoadCursor(NULL, IDC_ARROW);
wndcl.lpszClassName = classname;
wndcl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndcl.cbClsExtra = 0;
wndcl.cbWndExtra = 0;
wndcl.hbrBackground = CreateSolidBrush(RGB(240, 240, 240));//CreateSolidBrush(background);
wndcl.hIconSm = LoadIcon(NULL, IDI_APPLICATION); // 更改程序图标
wndcl.lpszMenuName = NULL;
wndcl.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
if (RegisterClassEx(&wndcl))return true;
return false;
}

HWND InitWindow(HINSTANCE hinstance, const TCHAR* classname, COLORREF background,
LRESULT(callbackfunc)(HWND, UINT, WPARAM, LPARAM), const TCHAR caption,
DWORD style, Rect place, HWND parent)
{
if (!RegisterWindow(hinstance, classname, background,callbackfunc))
{
MessageBox(NULL, TEXT("注册失败"), TEXT("错误"), MB_OK | MB_ICONERROR);
return NULL;
}
int left = place.position.x - place.size.x / 2.0;
int top = place.position.y - place.size.y / 2.0;
return CreateWindowEx(0, classname, caption, style,
left, top, place.size.x + 8, place.size.y + 30, parent, NULL, hinstance, NULL);
}

int __stdcall wWinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPWSTR cmdinstructor, int cmdnum)
{
MSG message;

HWND hwnd = InitWindow(hinstance, TEXT("WindowCourse"), RGB(240, 240, 240), CallBackFunc_Main, TEXT("窗口"),
    WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX & ~WS_THICKFRAME,
    Rect(Vec2(500, 300), Vec2(640, 480)), HWND_DESKTOP);
if (!hwnd)return 1;

ShowWindow(hwnd, cmdnum);

while (GetMessage(&message, NULL, 0, 0))
{
    TranslateMessage(&message);

    DispatchMessage(&message);
}

return message.wParam;

}

int main()
{
wWinMain(0, 0, 0, SW_SHOW);
return 0;
}

LRESULT __stdcall CallBackFunc_Main(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc, memDc;
PAINTSTRUCT ps;
switch (message)
{
case WM_CREATE:
{
RECT rect;
GetWindowRect(hwnd, &rect);
Vec2 windowsize = Vec2(rect.right, rect.bottom) - Vec2(rect.left, rect.top) - Vec2(8, 30);

    double paintsizeproportion_x = 0.9;
    double paintsizeproportion_y = 0.8;
    Rect paintregion(Vec2(windowsize.x * 0.7 * 0.5, windowsize.y * 0.5),
        Vec2(windowsize.x * 0.7 * paintsizeproportion_x, windowsize.y * paintsizeproportion_y));
    staPaint = CreateWindow(TEXT("STATIC"), TEXT(""),
        WS_CHILD | WS_VISIBLE | WS_OVERLAPPED | WS_BORDER | SS_BITMAP,
        paintregion.GetLeftTop().x, paintregion.GetLeftTop().y, paintregion.size.x, paintregion.size.y,
        hwnd, (HMENU)IDS_PAINTREGION, 0, 0);

    Rect verticalregion(Vec2(windowsize.x * 0.7 * (0.5 + 0.5 * paintsizeproportion_x)+10, windowsize.y * 0.5),
        Vec2(20, windowsize.y * paintsizeproportion_y));
    scrVertical = CreateWindow(TEXT("SCROLLBAR"), TEXT(""), WS_CHILD | WS_VISIBLE | WS_TABSTOP | SBS_VERT,
        verticalregion.GetLeftTop().x, verticalregion.GetLeftTop().y,
        verticalregion.size.x, verticalregion.size.y, hwnd, 0, 0, 0);

    Rect horizontalregion(Vec2(windowsize.x * 0.7 * 0.5, windowsize.y * (0.5 + 0.5 * paintsizeproportion_y)+10),
        Vec2(windowsize.x * 0.7 * paintsizeproportion_x, 20));
    scrHorizontal = CreateWindow(TEXT("SCROLLBAR"), TEXT(""), WS_CHILD | WS_VISIBLE | WS_TABSTOP | SBS_HORZ,
        horizontalregion.GetLeftTop().x, horizontalregion.GetLeftTop().y,
        horizontalregion.size.x, horizontalregion.size.y, hwnd, 0, 0, 0);

    verticalMax = 1170 - paintregion.size.y;
    horizontalMax = 1824 - paintregion.size.x;
    
    SCROLLINFO info;
    info.cbSize = sizeof(SCROLLINFO);
    GetScrollInfo(scrVertical, SB_CTL, &info);
    info.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
    info.nMin = 0;
    info.nMax = verticalMax + paintregion.size.y;
    info.nPage = paintregion.size.y;
    info.nPos = 0;
    SetScrollInfo(scrVertical, SB_CTL, &info, FALSE);

    GetScrollInfo(scrHorizontal, SB_CTL, &info);
    info.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
    info.nMin = 0;
    info.nMax = horizontalMax + paintregion.size.x;
    info.nPage = paintregion.size.x;
    info.nPos = 0;
    SetScrollInfo(scrHorizontal, SB_CTL, &info, FALSE);

    double buttonsizeproportion_x = 0.7;
    double buttonsizeproportion_y = 0.5;
    Rect inputregion(Vec2(windowsize.x * (0.7 + 0.3 * 0.5), windowsize.y * 0.25 * 0.5),
        Vec2(windowsize.x * 0.3 * buttonsizeproportion_x, windowsize.y * 0.25 * buttonsizeproportion_y));
    btnInput = CreateWindow(TEXT("BUTTON"), TEXT("输入地点"), WS_CHILD | WS_VISIBLE | WS_OVERLAPPED | WS_BORDER,
        inputregion.GetLeftTop().x, inputregion.GetLeftTop().y, inputregion.size.x, inputregion.size.y,
        hwnd, (HMENU)IDB_INPUT, 0, 0);
    Rect countregion(Vec2(windowsize.x * (0.7 + 0.3 * 0.5), windowsize.y * (0.25 + 0.25 * 0.5)),
        Vec2(windowsize.x * 0.3 * buttonsizeproportion_x, windowsize.y * 0.25 * buttonsizeproportion_y));
    btnCount = CreateWindow(TEXT("BUTTON"), TEXT("计算路径"), WS_CHILD | WS_VISIBLE | WS_OVERLAPPED | WS_BORDER,
        countregion.GetLeftTop().x, countregion.GetLeftTop().y, countregion.size.x, countregion.size.y,
        hwnd, (HMENU)IDB_INPUT, 0, 0);

    double staticsizeproportion_x = 0.7;
    double staticsizeproportion_y = 0.5;
    Rect beginregion(Vec2(windowsize.x * (0.7 + 0.3 * 0.5), windowsize.y * (0.25 * 2 + 0.25 * 0.5)),
        Vec2(windowsize.x * 0.3 * staticsizeproportion_x, windowsize.y * 0.25 * staticsizeproportion_y));
    staBegin = CreateWindow(TEXT("STATIC"), TEXT("起点:"), WS_CHILD | WS_VISIBLE | WS_OVERLAPPED | SS_CENTER,
        beginregion.GetLeftTop().x, beginregion.GetLeftTop().y, beginregion.size.x, beginregion.size.y,
        hwnd, (HMENU)IDS_BEGINPLACE, 0, 0);
    Rect endregion(Vec2(windowsize.x * (0.7 + 0.3 * 0.5), windowsize.y * (0.25 * 3 + 0.25 * 0.5)),
        Vec2(windowsize.x * 0.3 * staticsizeproportion_x, windowsize.y * 0.25 * staticsizeproportion_y));
    staEnd = CreateWindow(TEXT("STATIC"), TEXT("终点:"), WS_CHILD | WS_VISIBLE | WS_OVERLAPPED | SS_CENTER,
        endregion.GetLeftTop().x, endregion.GetLeftTop().y, endregion.size.x, endregion.size.y,
        hwnd, (HMENU)IDS_ENDPLACE, 0, 0);
}
    break;
case WM_COMMAND:
    switch (HIWORD(wParam))
    {
    case BN_CLICKED:
        switch (LOWORD(wParam))
        {
        case IDB_INPUT:
            responsecomponent = ResponseComponent::none;
            break;
        case IDB_COUNT:
            responsecomponent = ResponseComponent::none;
            break;
        }
        break;
    }
    break;
case WM_LBUTTONUP:
{
    short mouse_y = HIWORD(lParam);  // y
    short mouse_x = LOWORD(lParam);  // x
    RECT paintrect, winrect, rect;
    GetWindowRect(staPaint, &paintrect);
    GetWindowRect(hwnd, &winrect);
    rect.left = paintrect.left - winrect.left;
    rect.right = paintrect.right - winrect.left;
    rect.top = paintrect.top - winrect.top;
    rect.bottom = paintrect.bottom - winrect.top;
    if (mouse_x > rect.left && mouse_x < rect.right && mouse_y > rect.top && mouse_y < rect.bottom)
    {
        EnableWindow(scrVertical, FALSE);
        EnableWindow(scrHorizontal, FALSE);
        EnableWindow(scrHorizontal, TRUE);
        EnableWindow(scrVertical, TRUE);
        responsecomponent = ResponseComponent::paintregion;
    }
    else
    {
        EnableWindow(scrVertical, FALSE);
        EnableWindow(scrHorizontal, FALSE);
        responsecomponent = ResponseComponent::none;
        EnableWindow(scrVertical, TRUE);
        EnableWindow(scrHorizontal, TRUE);
    }
}
    break;
// case WM_LBUTTONUP:
//     
//     break;
case WM_ENABLE:
{
    int num = 0;
}
    break;
case WM_MOUSEWHEEL:
{
    // 高往下是负,往上是正
    short num_hi = HIWORD(wParam);
    switch (responsecomponent)
    {
    case ResponseComponent::none:
        break;
    case ResponseComponent::verticalscrollbar:
        if (num_hi < 0)verticalNow = min(verticalNow + 20, verticalMax);
        else if (num_hi > 0)verticalNow = max(verticalNow - 20, 0);
        SetScrollPos(scrVertical, SB_CTL, verticalNow, TRUE);
        InvalidateRect(hwnd, NULL, FALSE);
        break;
    case ResponseComponent::horizontalscrollbar:
        if (num_hi < 0)horizontalNow = min(horizontalNow + 20, horizontalMax);
        else if (num_hi > 0)horizontalNow = max(horizontalNow - 20, 0);
        SetScrollPos(scrHorizontal, SB_CTL, horizontalNow, TRUE);
        InvalidateRect(hwnd, NULL, FALSE);
        break;
    case ResponseComponent::paintregion:
    {
        SCROLLINFO scrollinfo;
        scrollinfo.cbSize = sizeof(SCROLLINFO);
        GetScrollInfo(scrVertical, SB_GRAD_TRI, &scrollinfo);
        if (num_hi < 0)
            imageProportion += 0.1;
        else if (num_hi > 0)
            imageProportion -= 0.1;
        InvalidateRect(hwnd, NULL, FALSE);
    }
        break;
    default:
        break;
    }
}
    break;
case WM_PAINT:
{
    RECT rect;
    hdc = BeginPaint(staPaint, &ps);
    memDc = CreateCompatibleDC(hdc);
    bmpImage = (HBITMAP)LoadImage(NULL, TEXT("map.bmp"), IMAGE_BITMAP, 1824, 1170, LR_LOADFROMFILE);
    SelectObject(memDc, bmpImage);
    GetWindowRect(staPaint, &rect);
    // BitBlt(hdc, 0, 0, rect.right - rect.left, rect.bottom - rect.top, memDc,
    //     horizontalNow, verticalNow, SRCCOPY);
    StretchBlt(hdc, 0, 0, rect.right - rect.left, rect.bottom - rect.top, memDc, horizontalNow, verticalNow,
        imageProportion* (rect.right - rect.left), imageProportion* (rect.bottom - rect.top), SRCCOPY);
    DeleteObject(bmpImage);
    DeleteDC(memDc);
    EndPaint(staPaint, &ps);
}
    break;
case WM_VSCROLL:
    switch (LOWORD(wParam))
    {
    case SB_PAGEDOWN:
        verticalNow += 20;
    case SB_LINEDOWN:
        verticalNow = min(verticalMax, verticalNow + 1);
        break;
    case SB_PAGEUP:
        verticalNow -= 20;
    case SB_LINEUP:
        verticalNow = max(0, verticalNow - 1);
        break;
    case SB_TOP:
        verticalNow = 0;
        break;
    case SB_BOTTOM:
        verticalNow = verticalMax;
        break;
    case SB_THUMBPOSITION:
        verticalNow = HIWORD(wParam);
        // EnableWindow(scrVertical, FALSE);
        // EnableWindow(scrVertical, TRUE);
        responsecomponent = ResponseComponent::verticalscrollbar;
        break;
    case SB_THUMBTRACK:
        verticalNow = HIWORD(wParam);
        break;
    default:
        break;
    }
    SetScrollPos(scrVertical, SB_CTL, verticalNow, TRUE);
    InvalidateRect(hwnd, NULL, FALSE);
    break;
case WM_HSCROLL:
    switch (LOWORD(wParam))
    {
    case SB_PAGERIGHT:// 用户单击滚动条右方的滚动条轴
        horizontalNow += 20;
        break;
    case SB_PAGELEFT:
        horizontalNow -= 20;
        break;
    case SB_LINELEFT:// 用户单击左滚动箭头
        horizontalNow = min(horizontalNow + 1, horizontalMax);
        break;
    case SB_LINERIGHT:
        horizontalNow = max(horizontalNow - 1, 0);
        break;
    case SB_THUMBTRACK:// 拖动滑块
        horizontalNow = HIWORD(wParam);
        break;
    case SB_THUMBPOSITION:// 拖动后松开
        horizontalNow = HIWORD(wParam);
        // EnableWindow(scrHorizontal, FALSE);
        // EnableWindow(scrHorizontal, TRUE);
        responsecomponent = ResponseComponent::horizontalscrollbar;
        
        break;
    }
    SetScrollPos(scrHorizontal, SB_CTL, horizontalNow, TRUE);
    InvalidateRect(hwnd, NULL, FALSE);
    break;
break;
case WM_DESTROY:
    PostQuitMessage(0);
    break;
default:
    break;
}
return DefWindowProc(hwnd, message, wParam, lParam);

}

问题补充:


具体来说就是这个问题怎么解决

才出昆仑便不清的主页 才出昆仑便不清 | 初学一级 | 园豆:59
提问于:2022-09-05 17:01
< >
分享
所有回答(1)
0

在代码中,在处理WM_LBUTTONUP(鼠标左键点击)事件时,禁用并立即启用了滚动条。这可能导致滚动条暂时无法接收消息,从而导致读取滚轮信息的功能失效。

如果主要目标是防止滚动条在点击静态文本区时闪烁,以下是一些可能的解决方案:

  1. 降低重绘的频率:当你需要改变窗口样式或者其它属性,并且不希望用户看到窗口改变的过程,可以采用下面的方式:

    SetWindowRedraw(scrVertical, FALSE);
    // 修改窗口属性的代码
    SetWindowRedraw(scrVertical, TRUE);
    

    这会在修改窗口属性的过程中关闭窗口的绘制,直到属性修改完成后再开启。这样就避免了窗口在修改期间的重绘,也就避免了滚动条的闪烁问题。

  2. 更改绘图策略:如果滚动条的闪烁是由于重绘引起的,可以尝试更改绘图策略。例如,使用双缓冲技术来减少或消除闪烁。

  3. 使用自定义滚动条:如果上述方法仍不能解决问题,那么可能需要考虑使用自定义滚动条。这将允许你有更多的控制,您可以自定义滚动条的外观和行为。

npe0 | 园豆:1299 (小虾三级) | 2023-12-12 17:40
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册