Hi Aldo,

Four topics:

1) Patch for some "uninitialized" warnings produced by Win32::GUI for one of my GUI programs

2) Accelerator keys

3) Stuttering typing during repeated calls to DoEvents

4) resize cursor


     Topic 1

Here is the fix (suggested by Jan Dubois, after I pinpointed where the problem was happening) for a couple "uninitialized" references made by Win32::GUI. Added code in red. Can you merge this into your development source? I've tested that tooltips still work afterwards, and that the warning message no longer gets generated.

GUI.xs:

// #### add (or create) the tooltip
if(perlcs.szTip != NULL) {
if(perlcs.hvParent != NULL) {
if(perlcs.hTooltip == NULL) {
SV** t;
t = hv_fetch_mg(NOTXSCALL perlcs.hvParent, "-tooltip", 8, 0);
if(t != NULL && SvOK( *t )) {
perlcs.hTooltip = (HWND) SvIV(*t);
}
}
if(perlcs.hTooltip == NULL) {
#ifdef PERLWIN32GUI_STRONGDEBUG
printf("XS(Create): creating -tooltip...\n");
#endif
perlcs.hTooltip = CreateTooltip(NOTXSCALL perlcs.hvParent);
}
}


     Topic 2

Accelerator keys: seems like there's a lot of work to do to make them work. Have you done or are you planning to do this work in the short term? If I do some of the work for this, is there any chance it will get merged into the real source for Win32::GUI ? Do you have any recommendations for what approach (data structures and/or code paths) should be taken for this, or can I just do what I want, as long as it works !?


     Topic 3

Stuttering typing during repeated calls to DoEvents. I really don't have a lot of understanding of this problem. I can write a "pure perl" test case that seems to do the same things as Win32::GUI with respect to message queue handling, and it doesn't stutter. When I added traces for the incoming messages, and for the calls to the DefWindowProc (in all the places I could find that it is called) it seems to me like

Win32::GUI gets 1 WM_KEYDN, but 2 WM_CHAR and WM_KEYUP messages for each keystroke pressed (from traces in DoEvents-- I added traces there, and each other places that GetMessage and PeekMessage was called).

However, I must not have found all the places where they get processed: I'd have thought they'd be passed through to DefWindowProc, but after tracing all the references to DefWindowProc that I could find, I still couldn't see where they were processed! So I set conditional breakpoints on every MessageLoop function in GUI_MessageLoops.cpp, looking for a WM_CHAR value in uMsg, and still no hits.

So I must confess to ignorance about how to debug this one. Give me some ideas, and I'll try to do some more.


     Topic 4

GUI 0.0.665 seems to have lost the ability to show the specialized arrow cursors for resizing during when the cursor hovers over the borders. While the -resizable => 0 option can eliminate the ability to resize things, -resizable => 1 (or unspecified) allows resizing to happen, but the fancy cursors are not used. I found the following discussion of the those fancy cursors in MSDN. But I can't see where you handle the WM_NCHITTEST message at all. This would imply that you pass it on to the default window procedure. I set some conditional breakpoints on all the GUI_MessageLoop functions for WM_NCHITTEST, and this was more fruitful than trying to find WM_CHAR messages. I was able to hit one, and step it through to the DefWindowProc, which return HTBORDER (which means you can't resize, and means the cursor doesn't change shape). Why HTBORDER is returned by the DefWindowProc is a mystery to me... I don't have a clue at present about if the hwnd parameter passed is the correct one, or if all of its parameters reflect the fact that the window was created with WS_THICKFRAME (which it was, in my case). From the text from MSDN (below), it explains that the action of the DefWindowProc in this case is exactly what you should do if you don't want the arrows to show up!

I don't quite understand why there are so many different places to call the default window procedure (I'm barely figuring out XS, much less all of Win32::GUI). Seems like if they were all unified, that it would be easier to instrument/trace messages that get passed to the default window procedure and the responses.

The following from C++ Q&A, Periodicals 1996, in MSDN for VC++6.0:

How does Windows know to display that little size arrow cursor when the user moves the mouse into the frame of a sizable window? By sending the window a special message, WM_NCHITTEST. The window returns a code indicating which area of the window the mouse is in. HTCAPTION says the mouse is in the caption; HTMINBUTTON says it's in the minimize button, and so on (see "Dave's Top Ten List of Tricks, Hints, and Techniques for Programming in Windows," MSJ October 1992, for more information on WM_NCHITTESTEd.). Of special relevance now are the hit test codes HTLEFT, HTRIGHT, HTTOP, HTTOPLEFT, HTTOPRIGHT, HTBOTTOM, HTBOTTOMLEFT, and HTBOTTOMRIGHT. As the names suggest, these codes indicate that the mouse is in some part of the window frame where sizing is allowed. For example, HTBOTTOMRIGHT tells Windows the mouse is in the bottom, right corner of the frame. When your window proc returns HTBOTTOMRIGHT, Windows displays the northwest/southeast arrow cursor to cue the user that he can size the window by dragging. Likewise, if you return HTLEFT or HTRIGHT, Windows displays the east-west arrow to indicate that the window can be sized horizontally. The Windows default window procedure, DefWindowProc, which is where MFC routes all unhandled messages, figures out where the mouse is and returns the appropriate HTxxx code. If the window doesn't allow sizingthat is, if it has WS_BORDER instead of WS_THICKFRAME as its border stylethen DefWindowProc returns another code, HTBORDER, that tells Windows the mouse is in the border but sizing is not allowed. In that case, Windows displays its normal arrow cursor and sizing is not allowed.

Suppose you had a WS_THICKFRAME border but implemented your own handler for WM_NCHITTEST that always returns HTBORDER when the mouse is in the border? That's exactly what I did to fix MONITOR (see Figure 13). The CMonitorWindow constructor creates the window with the WS_THICKFRAME border style to give it the thick sizeable frame. This eliminates the problem with the two-pixel high client area. But then, to prevent the user from sizing the window, I implemented my own WM_ONNCHITTEST handler. CMonitorWindow::OnNcHitTest first calls the base class CFrameWnd::OnNcHitTest to get the hit test code DefWindowProc would normally return, then CMonitorWindow mungs it. If the normal response would be HTTOP or HTBOTTOM, CMonitorWindow returns HTBORDER instead. This has exactly the same effect as a nonsizeable border. What's even cooler is that if CFrameWnd::OnNcHitTest returns HTLEFT, HTTOPLEFT or HTBOTTOMLEFT (any of the LEFT codes), CMonitorWindow returns HTLEFT, and if CFrameWnd returns HTRIGHT, HTTOPRIGHT, or HTBOTTOMRIGHT, CMonitorWindow returns HTRIGHT. The result is that the user can still size the window horizontally, which makes sense for a window that's only a title bar. If the user moves the mouse into one of the corners, Windows displays an east-west size arrow cursor, not a diagonal one. Pretty neat. If you don't want this feature, you can just return HTBORDER in all cases.

--
Glenn -- http://nevcal.com/
===========================
Wise men talk because they have something to say.
Fools talk because they have to say something." -- Plato



Reply via email to