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