简体   繁体   English

滚动文本在 static 控件(C++ WinAPI)中被否定

[英]Scrolling text gets negated in static control (C++ WinAPI)

I have some weird control,我有一些奇怪的控制,

CreateWindowEx(!tset&USE?WS_EX_OVERLAPPEDWINDOW:0,
tset&USE?"static":"edit",0,WS_CHILD|WS_VISIBLE|
(!tset&USE?ES_MULTILINE|ES_WANTRETURN|ES_AUTOVSCROLL|WS_VSCROLL //when it's edit
:SS_NOTIFY|SS_EDITCONTROL),5,60,390,474,hwnd,HMENU(10),0,0); //when it's static
SetWindowSubclass(GetDlgItem(hwnd,10),tset&USE?BOR:NoMenu,0,0);

whose everything depends on whether themes are active.他们的一切都取决于主题是否活跃。 Here tset is an instance of enum type for bit flags.这里tset是位标志的enum类型的实例。 Everything is fine except scrolling when the control is in static mode.一切都很好,除了当控件处于 static 模式时滚动。 It wasn't receiving WM_MOUSEWHEEL messages, I made it receive them in the following way:它没有收到WM_MOUSEWHEEL消息,我让它通过以下方式接收它们:

LRESULT CALLBACK BOR(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp,UINT_PTR,DWORD_PTR)
{
    if(msg==WM_MOUSEMOVE&&GetDlgCtrlID(hwnd)==10)
    {
        POINT x{LOWORD(lp),HIWORD(lp)}; ClientToScreen(hwnd,&x);
        RECT rc; GetWindowRect(hwnd,&rc); if(PtInRect(&rc,x)&&GetCapture()!=hwnd){SetCapture(hwnd); hwnd3=SetFocus(hwnd);}
        if(!PtInRect(&rc,x)&&GetCapture()==hwnd){ReleaseCapture(); SetFocus(hwnd3);} //hwnd3 is an instance of HWND defined in global scope, for giving focus back
    }
    if(msg==WM_MOUSEWHEEL)
    {
        RECT rc; GetWindowRect(GetParent(hwnd),&rc);
        HRGN x; GetWindowRgn(GetParent(hwnd),x);
        ScrollWindowEx(hwnd,0,short(HIWORD(wp)),0,0,x,&rc,SW_INVALIDATE|SW_ERASE);
        ShowWindow(GetParent(hwnd),SW_HIDE); ShowWindow(GetParent(hwnd),SW_SHOW);
        SetFocus(hwnd);
        return 1;
    }
    return DefSubclassProc(hwnd,msg,wp,lp);
}

Now when mouse enters client area of my control, if it's in static mode, it captures mouse and gets focus.现在当鼠标进入我的控件的客户区域时,如果它处于 static 模式,它会捕获鼠标并获得焦点。 So it intercepts WM_MOUSEWHEEL messages in its subclass callback function and I can scroll my control in the static mode.因此,它在其子类回调 function 中拦截WM_MOUSEWHEEL消息,我可以在 static 模式下滚动控件。 Here's the exact problem: few milliseconds later, right after its text is scrolled, the window somehow updates itself to its initial unscrolled state.这是确切的问题:几毫秒后,在其文本滚动之后, window 不知何故将自身更新为其初始未滚动的 state。 And my efforts get negated.我的努力被否定了。 Is it clear why it behaves like this, and how to fix that?是否清楚它为什么会这样,以及如何解决这个问题?

@Edit: Why don't I simply add WS_VSCROLL to its static version? @Edit:我为什么不简单地将WS_VSCROLL添加到其 static 版本中? Because it has SS_NOTIFY style and I need it to respond to WM_COMMAND messages somehow else.因为它具有SS_NOTIFY样式,我需要它以其他方式响应WM_COMMAND消息。 This is why I tried scrolling it manually.这就是我尝试手动滚动它的原因。

@Update: @更新:

Here in both screenshots the text length is the same.在这两个屏幕截图中,文本长度是相同的。 When the control is in edit state, its vertical scrollbar is proper.当控件在编辑 state 时,它的垂直滚动条是正确的。 But when it's in static state the vertical scrollbar doesn't match the actual text length.但是当它在 static state 中时,垂直滚动条与实际文本长度不匹配。 Besides, the scrollbar is always at the same size and same position independent from text length and it's also unscrollable.此外,滚动条始终保持相同的大小和相同的 position 与文本长度无关,并且它也是不可滚动的。 Why may be the reason of it behaving like this?为什么可能是它表现得这样的原因?

@Update: Thanks to @enhzflep's comment, problem is easily solved some other way. @Update:感谢@enhzflep 的评论,问题很容易通过其他方式解决。

In the interests of removing the question from the Unanswered list, I'll repeat and expand upon one of the comments.为了从未回答列表中删除该问题,我将重复并扩展其中一条评论。

Looking at the images, we can immediately see a clear difference in the way they're each presented.查看图像,我们可以立即看到它们各自呈现方式的明显差异。 The left image has each line starting with a different character, while the right image always starts with the same character.左图的每一行都以不同的字符开头,而右图总是以相同的字符开头。 They also have very differently sized thumbs in the scroll-bar.它们在滚动条中也有非常不同大小的拇指。

Since the problems seem to be stemming from trying to use two different controls to achieve essentially the same task, I'd suggest always using an edit control.由于问题似乎源于尝试使用两个不同的控件来完成基本相同的任务,因此我建议始终使用编辑控件。 (this is the one that appears to behave nicely, and is the one that doesn't wrap the text) (这是一个表现得很好,并且不换行的那个)

Rather than use two different types of control, I suggest just toggling the read-only flag.我建议不要使用两种不同类型的控件,而是切换只读标志。 With luck (.) the only difference now will be the way mouse and keyboard messages are handled - hopefully you'll get similar behaviour and appearance with such an approach.运气好(。)现在唯一的区别是处理鼠标和键盘消息的方式 - 希望你会通过这种方法获得类似的行为和外观。 The message I'm thinking of that will achieve this is EM_SETREADONLY .我想实现这一点的消息是EM_SETREADONLY

Although the question has been successful answered, I can't find reference in the Microsoft docs to support my theories, thus used language like 'hopefully'.尽管问题已成功回答,但我在 Microsoft 文档中找不到支持我的理论的参考资料,因此使用了“希望”之类的语言。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM