Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Westi on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Specifying the location of a shortcut menu

Status
Not open for further replies.

Mike Lewis

Programmer
Jan 10, 2003
17,516
Scotland

When you use DEFINE POPUP to create a shortcut menu, the FROM clause specifies the top left corner where the menu is to be located. Typically, this is set to MROW(), MCOL(), which means the menu pops up at the mouse pointer, which is usually what you want.

In my case, however, I want the menu to pop up in a specific location relative to the main window, regardless of where the mouse is. I know I can use actual numbers in place of MROW(), MCOL(), for example:

DEFINE POPUP shortcut SHORTCUT RELATIVE FROM 20, 100

The trouble is that these numbers are in Foxels. I know where I want to put my menu, but I only know the location in pixels.

My question is: Is there a way of specifying the menu location in pixels? Or, alternatively, is there a reliable way of converting a pixel location to Foxels?

Thanks in advance.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

My Visual FoxPro site: www.ml-consult.co.uk
 
I want the menu to pop up in a specific location relative to the main window

I had a similar problem and I gave up on popups in the end. Instead I wrote a borderless, title-less form which held a list box of exactly the same size. The various events that call this form into being also set the PopupTop and PopupLeft properties of the current form and the list form reads these as it loads itself so as it knows where it has to appear.

Geoff Franklin
 
MikeLewis

You can specify the scalemode for MROW() and MCOL()

Code:
MROW([cWindowName | 0 [, nScaleMode]])

In your case the scalemode should be 3 (Pixels) rather than 0 (Foxels)


Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
ReFox XI (www.mcrgsoftware.com)
 

Mike (Gagnon),

You can specify the scalemode for MROW() and MCOL()

Yes, but that only tells me the location of the mouse.

What I want is to specify the position of the menu, regardless of where the mouse is sitting. In other words, I want to specify the co-ordinates in the FROM clause, but in pixels rather than foxels.

Geoff,

I had a similar problem and I gave up on popups in the end.

Actually, that's quite encouraging (in a way). If you couldn't find a solution, it means that there probably isn't one.

I've considered creating my own popup with the sort of borderless form you described. I've also got a third party ActiveX control that creates popups with much more precision than the VFP version. I just wanted to be sure I wasn't missing something obvious.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

My Visual FoxPro site: www.ml-consult.co.uk
 
Actually Mike, MROW() and MCOL() now have a scalemode parameter. I don't know when they added it, but I see it in VFP 9.
Code:
MROW([cWindowName | 0 [, nScaleMode]])
MCOL([cWindowName | 0 [, nScaleMode]])
The default is foxels, but using 3 will utilize pixels.

-Dave Summers-
[cheers]
Even more Fox stuff at:
 

Dave,

Thanks for the response, but this is just the same as what Mike Gagnon suggested. As you can see from my reply to him, I don't need to know where the mouse is located. I want to specify explicit co-ordinates for the menu.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

My Visual FoxPro site: www.ml-consult.co.uk
 
Woops. I didn't see Mike Gagnon's response.

Since foxels is determined by the current font, size, and all that good stuff, you would have to do all the usual converting using FONTMETRICS() and the like to get a conversion.

I'm wondering though, if you could use a combination of Thisform.width, Thisform.Height, WCOLS() and WROWS() to arrive at a valid calculation?


-Dave Summers-
[cheers]
Even more Fox stuff at:
 

Dave,

Hmm. You might be on to something.

Given that I want to do this relative to the main VFP window, it seems to me that _screen.Height / Wrows() should give a vertical foxel-to-pixel conversion factor.

Similarly, _screen.Width / WCols should give the equivalent horizontal factor.

Let me experiment along those lines. I'll report back.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

My Visual FoxPro site: www.ml-consult.co.uk
 

Well, I've come to a dead end on this one.

Following Dave's suggestion, I tried this:

Code:
* tnLeft is the horizontal position where I want the 
* menu to appear, relative to the outer window.
* tnTop is the equivalent vertical position. Both
* are in pixels.

* Convert pixels to foxels.
lnFoxLeft = tnLeft / (_screen.Width / WCOLS())
lnFoxTop = tnTop /  (_screen.Height / WROWS())

* Display the menu
DEFINE POPUP shortcut SHORTCUT FROM lnFoxTop, lnFoxLeft

But this gives consistently bad results. In most cases, the menu is too far to the right and too far down.

Also, the results vary according to the size of the outer window, which I don't understand. I would have thought that the ratio between the number of rows (as per WROWS()) and the height in pixels (as per _screen.height) would be constant (for a given font size).

Oh, well. Unless someone can tell me where I'm going wrong, I might have to give this one up.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

My Visual FoxPro site: www.ml-consult.co.uk
 

Dave,

Good question.

My aim is to create a command button which, when clicked, opens a menu -- just like the ones you see in many Windows applications. I want the menu to appear just below the button, with its left edge lined up with the left edge of the button.

I know the button's location, relative to its container, in pixels (obviously). From that, I can work out the location relative to the outer window, again in pixels. That's the location at which I want to open the menu.

Any further suggestions will be gratefully received.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

My Visual FoxPro site: www.ml-consult.co.uk
 
How about going at it from the other direction?
I changed the scalemode of the form to 0 (foxels) then used the coordinates of the button:
Code:
DEFINE POPUP popRelat FROM ;
   dave.command1.top + ;
   dave.command1.height, ; 
   dave.command1.left 
DEFINE BAR 4  OF popRelat PROMPT '4444'
DEFINE BAR 3  OF popRelat PROMPT '3333'
DEFINE BAR 2  OF popRelat PROMPT '2222'
DEFINE BAR 1  OF popRelat PROMPT '1111'
ACTIVATE POPUP popRelat
It may take a little twiddling to get it exactly where you want it, but it seemed to work for the different pushbuttons on my form.

-Dave Summers-
[cheers]
Even more Fox stuff at:
 
Mike

Another alternative might be to utilise a shortcut menu as opposed to a popup.

The code would be something like
Code:
[COLOR=blue]MOUSE AT 10,10 PIXELS
INKEY(0.001)
DO shortcutmenu.mpr[/color]
The INKEY() is required to enable the mouse to position itself before calling the shortcut menu.

Unless you specify a window, the mouse coordinates will be relative to _SCREEN.

FAQ184-2483 - answering getting answered.​
Chris [pc2]
PDFcommander.com
PDFcommander.co.uk
 

OK, I've seen where I've been going wrong.

First, I'll comment on the above replies.

Dave:
I like your idea of changing the scalemode. You code looks like its calculating the position of the button relative to its form (or other parent container), so presumably I'd need to adjust that to make it relative to the main window. It's something to keep in mind.

Chris:
If I understand this right, you are suggesting that I actually move the mouse to where I want the menu to appear, then use MROW() and MCOL() to position the menu. I can see that this would work, although (I'm sure you'll agree) it's a bit kludgy. Of course, I'd have to move the mouse back again to its original position, and I couldn't do that until after the menu has closed. Maybe that doesn't matter, but it might look odd to the user.

For what it's worth, here's how I solved the problem.

I was originally using this code (thank to Marcia Akins) to calculate the horizontal position of the mouse relative to the main window:

lnLeft = OBJTOCLIENT(this, 2) + OBJTOCLIENT(thisform, 2)

What I hand't realised is that this in fact gives the position relative to the physical screen, not the main VFP window.

Once I realised that, I just subtracted OBJTOCLIENT(_screen, 2) to get the required figure. Similarly for the vertical co-ordinate, except that I also factored in SYSMETRIC(9) to allow for the main window's title bar.

(It's just occurred to me that this will go wrong if there are any docked toolbars present, but I can deal with that.)

So, that gave me the correct location for my menu, in pixels. To convert it to foxels, I followed my earlier idea of dividing by (_screen.Width / WCOLS()) or (_screen.Height / WROWS()).

Having done that, it's working perfectly.

Thanks to you all for your ideas and comments.

Mike



__________________________________
Mike Lewis (Edinburgh, Scotland)

My Visual FoxPro site: www.ml-consult.co.uk
 
Mike

Glad you got it working.

Mike said:
Of course, I'd have to move the mouse back again to its original position...
Making a selection from the menu should negate the need to do this.


The other question to you is why are you using DEFINE POPUP as opposed to using a shortcut menu?

FAQ184-2483 - answering getting answered.​
Chris [pc2]
PDFcommander.com
PDFcommander.co.uk
 

Chris,

Making a selection from the menu should negate the need to do this.

That's true. They might even see it as a benefit -- saves having to move the mouse from whereever it was before. On the other hand, it might not look so good if they use the keyboard to make the selection.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

My Visual FoxPro site: www.ml-consult.co.uk
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top