Click to See Complete Forum and Search --> : How does this work?
wilton
January 4th, 2000, 03:31 AM
I wrote the code below based on help from others and resources I found on the net. I don't understand why it works though. What does the number of twips per pixel have to do with which mouse button has been clicked? Anyone that can provide insight on this would be viewed as a savior. Thank You.
private Sub FORM_MouseMove(Button as Integer, Shift as Integer, X as Single, Y as Single)
static lngMsg as Long
lngMsg = X / Screen.TwipsPerPixelX
'MsgBox lngMsg, vbOKOnly, "OK"
Select Case lngMsg
Case WM_RBUTTONUP
Case WM_LBUTTONDOWN
'MsgBox lngMsg, vbOKOnly, "OK"
Debug.print lngMsg
frmMain.WindowState = Normal
frmMain.Show
Case WM_LBUTTONDBLCLK
Case else
End Select
wilton
January 4th, 2000, 03:47 AM
Why does x/screen.twipsperpixelx is always the same value no matter what resolution or place you click on the status area? That is the real question I need answered.
Chris Eastwood
January 4th, 2000, 03:51 AM
It's a slimy hack used to get the message from the System Tray. The reason that it only returns one value is probably because you've only setup one message in your NOTIFYICONDATA structure's '.uCallBackMessage' property.
The ideal way to capture system tray messages is to use subclassing (see my example at http://codeguru.developer.com/vb/articles/1715.shtml) - the method using 'x / screen.twips...' does work though, although you are limited if you want to use more than one taskbar icon (well, not strictly limited, it just get's a bit messy).
Chris Eastwood
CodeGuru - the website for developers
http://codeguru.developer.com/vb
wilton
January 4th, 2000, 04:01 AM
Why not just use the individual codes that x returns? Why bother with the x/twips or even sub classing. I've done some experimenting and found that depening on what mouse button you hit gives a unique x value(duh). So why then use the (slimy) hack?
Chris Eastwood
January 4th, 2000, 04:15 AM
I can't remember exactly how the 'slimy hack' works - I think the value returned by X is a mish-mash of loword/hiword stuff, but that doesn't explain how Screen.TwipsPerPixelX would get the correct value back out from 'X'.
I've used the 'X / Screen....' for a couple of years and never had any problem with it, like I said before, if you really want to get involved with the system tray and it's messages then the best way is probably through subclassing (see the sample I gave the link to earlier).
You *should* be ok with the hack though if you are only using one icon in the system tray at a time (each icon added needs it's own individual ID in it's NOTIFYICONDATA structure, and the 'x / screen...' method can't tell you what Icon was clicked - unless you add an individual picturebox for each icon, then the same code for each picturebox......) Subclassing the messages from the system tray can tell you exactly which of the icons was clicked and what the correct message is.
Chris Eastwood
CodeGuru - the website for developers
http://codeguru.developer.com/vb
wilton
January 4th, 2000, 04:29 AM
I did some digging and found that the constants that everyone uses for wm_whatever are just hex values that have been previously calculated out to what an x value(what type of click it was) over a twips value would be. The questions then are why bother with the extra lines of code asking for x/twips? From what I can tell, twips per pixel x is always the same regardless of screen resolution. Is there a different set of x values depending on what icon you punch? Or are they always the same? I assume they are the same at all times. So if you're using just one icon like most programs do, then it might just be easier to recalculate the constants post them on a website and just tell people to use the x value and the new constants. Whatta ya think?
wilton
January 4th, 2000, 04:33 AM
Something I forgot to ask is why use a picture box? Why not just use form_mousemove? Is there a benefit to using a picture box?
Chris Eastwood
January 4th, 2000, 04:39 AM
Well, it's just a personal preference really. You don't even need to use a picturebox (any control with an HWND property would do).
The fact that the PictureBox is hidden from the form in the first place (ie. Picture1.visible = false) is a good reason - that way, the picturebox only receives the mouse messages from the system tray (as that's where you set the NOTIFYICONDATA structures HWND to). Using Form_MouseMove could prove a bit problematic as the routine will be called everytime the mouse moves over the form *and* when the mouse moves over the icon in the system tray.
Chris Eastwood
CodeGuru - the website for developers
http://codeguru.developer.com/vb
wilton
January 4th, 2000, 04:52 AM
Only controls or items that are not visible recieve the mouse move event? Why wouldn't the pbox recieve the event everytime the form did? Does the pbox recieve the event both when the form(app) is visible and when it is hidden and minimized? Same as the form? But then you don't have to worry about the mouse clicks on the form conflicting with those of the mouse move event, right? By using the pbox the status area icon is connected to that control and not the form?
Chris Eastwood
January 4th, 2000, 04:55 AM
The 'WM_' values relate to messages that windows fires off all the time - it wouldn't be a good idea to ignore their values and simply check for 'x'. These values are obtained from the WinAPI viewer that comes with VB (or by hacking around in the C header files that come with VC++6). It's much better to leave these values as they are and check for them in the 'Select Case' statement later in your code.
As for not checking the value of Screen.TwipsPerPixelX - I'm not sure about that. The MSDN states that this value can vary between different monitors (although it's a bit tricky to test it as I only have one available). I still don't see how this can affect the 'x / screen.' value (although that does return a 'whole' number.
Chris Eastwood
CodeGuru - the website for developers
http://codeguru.developer.com/vb
Chris Eastwood
January 4th, 2000, 05:03 AM
>Only controls or items that are not visible recieve the mouse move event?
Nope - when you setup the NOTIFYICONDATA structure :
'
' Setup the System Tray Icon
'
Dim tTrayStuff as NOTIFYICONDATA
'
With tTrayStuff
.cbSize = len(tTrayStuff)
.hwnd = Picture1.hwnd
.uId = 1&
.uFlags = NIF_ICON Or NIF_TIP Or NIF_MESSAGE
.uCallBackMessage = WM_MOUSEMOVE
.hIcon = me.Icon
.szTip = "Your Tooltip Goes Here" & vbNullChar
Shell_NotifyIcon NIM_ADD, tTrayStuff
End With
'
Where you set the '.hwnd' of the structure tells windows that this control (picture1) will be capturing the events for that icon in the taskbar. The '.uCallBackMessage' tells windows that we want to retrieve messages for the windows mouse move event (picture1). The actual message is passed to the mousemove event of the picture1 picturebox in the 'X' parameter (although it's still beyond me why Screen.twips... would work).
>Why wouldn't the pbox recieve the event everytime the form did?
Because we've set it to be invisible. The above structure tells windows to post any messages from our icon to the code for the mousemove event for the picture box (we aren't actually moving the mouse over the picturebox at any point in the code).
I'd shy away from using the form_mousemove because you may want to code some other kind of functionality for that procedure (keeping the code for the icon related to a hidden control is a more preferable way IMHO).
Chris Eastwood
CodeGuru - the website for developers
http://codeguru.developer.com/vb
wilton
January 4th, 2000, 05:07 AM
Yeah, I like the picture box idea a lot more. Then you don't have all these mouse move events firing every time the mouse hits the back of the form. Thank you for the help
wilton
January 4th, 2000, 05:26 AM
I have a 17" monitor set to 1280x1024 or something like that. I get 15 twipPerPixel. I always get that despite my resolution. Try it on your computer and see what you get. I'm very curious. If you "reverse engineer" the Hex numbers for wm_whatever, then you find that they are of course just the hex equiv of x(I get 7695 for a left click down again despite resolution) over 15 twips per pixel for a total of 513(this is the hex equiv (wmlbuttondn)). I also tried this on a fifteen inch monitor using again different resolutions and it still gave me the exact same numbers. I think the point of using the the twipPPxl is to give the result code some uniformity(The x number seems to be a factor multiple of 15(tpp) everytime). Just a thought. I think you could lose it and it wouldn't change the functionality of the program.
Try it on your computer and post what you get(tpp and x value. I'd be willing to bet you get the exact same thing I do.).
Chris Eastwood
January 4th, 2000, 05:42 AM
I get 15 too - although I still strongly advise against having to reconfigure those WM_ constants (you'll only regret it later).
I've just checked on the MSDN for their systray sample (article Q176085). Their example also uses the 'x / screen.twipsperpixelx' method (they don't explain why) - but they do say :
'the value of X will vary depending upon the scalemode setting
If me.ScaleMode = vbPixels then
msg = X
else
msg = X / Screen.TwipsPerPixelX
End If
- it would appear then that the message returned (eg WM_LBUTTONDBLCLK) is actually returned in the X value in PIXELS (strangely enough). This makes more sense now that you know that TwipsPerPixelX can change between computers / monitors (at least according to the MSDN).
Chris Eastwood
CodeGuru - the website for developers
http://codeguru.developer.com/vb
wilton
January 4th, 2000, 04:38 PM
That makes a lot more sense. Thanks for looking that up.
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.