Does XUL support different modality scopes? - firefox

Is it possible to create a dialog using XUL (specifically in Firefox) that is:
Always-on-top but does not blocking user interaction with a page
and/or
Only tab modal, not window modal
?

You can surely have a non blocking Dialog, but it will go to the background when you click the window. For reference see this:
window.openDialog("chrome://membees/content/dialog.xul",
"","centerscreen=yes, all=no, titlebar=yes, chrome=yes, toolbar=yes,
dialog=no, resizable=no,modal=no","");
But if you want a bit more of control you can create a panel instead, and take advantage of the level property:
level
Specifies whether the panel appears on top of all windows, or just on
top of the window the panel is in. If this attribute is not set, the
popup window level depends on the platform. On Linux, the default
value is top, otherwise, the default value is parent. If a panel has
one or more text fields, this attribute should not be set, otherwise
IME or on-screen keyboard popups will appear incorrectly. For these
reasons, you should avoid setting the level if not needed.
top
The panel is shown in front of all other normal windows, including those of other applications.
parent
The panel is shown just above the window the panel is in, but behind
other windows above it. If anchored, the child window maintains its
relative position to its parent window.
floating
The panel floats above the window the panel is in. On Mac, the panel
is only visible when the application is active.
To create it you have to add it to the base element <popupset> in your overlay, and then you open it with:
openPopup(anchor,position,x,y,isContextMenu,attributesOverride,triggerEvent )

Related

How can i draw to or add a custom button to every window of all applications?

I have seen several tools adding a custom button and/or drawing on the title bar of all windows of all applications in Windows. How is that done?
Extra points for an example in Delphi.
EDIT:
I found something for dotNET that does this:
http://www.thecodeking.co.uk/2007/09/adding-caption-buttons-to-non-client.html#.VdmioEDenqQ
How I see this job:
First of all we should be able to paint this button on the our own window caption. This procedure will be used later
This part of the program enumerates the active and visible windows
This part of the program using injection attach our dll to enumerated windows
From injected dll we can draw the button on the window caption
Inside this dll we should process the click on the button
We should have mechanism to send result to our main program
I haven't done this, so the following is what I would investigate if I were to try:
For each application / each top-level window:
Create a floating window and position it over the title bar wherever you want it to sit. Set up the parent / child relationship, but this window is part of your own process. (There are occasionally problems parenting a window from one process to one from another process, but try. I'd avoid injecting into other processes if possible.)
You can investigate the window flags to see if the window has a title bar (ie if you should add a button) via GetWindowLong with GWL_STYLE looking for WS_CAPTION. The same call will also let you see the type of caption / frame, which you can combine with GetSystemMetrics with, eg, SM_CYDLGFRAME to figure out the right size for your button on this specific window's title bar.
This window is now your button: paint, handle clicks etc as appropriate.
Make it a non-focusable window so that clicks to it don't take focus away from the window is is on the title bar of. You don't want clicking it to make the title bar change colour, for example. Do this by setting the WS_EX_NOACTIVATE window flag, something like: SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) orWS_EX_NOACTIVATE).
The main problem is to keep it positioned correctly when the window moves, is resized, etc. To do this, install a hook for the system move events. You can also hook minimize and restore via EVENT_SYSTEM_MINIMIZESTART and EVENT_SYSTEM_MINIMIZEEND. This will allow you to keep track of all windows moving around onscreen, such that you can adjust the button-window position if necessary.
That gives you a window which you can paint as a button (and respond to clicks etc), that visually is "attached" to other windows so it stays in the same place as the user drags the title bar, minimizes or maximises the app, etc, and that is in your own process without cross-process problems.

Get the position of the control in the Windows openfile dialog

I my application, I have added a dropdown box to the standard windows file open dialog. This works fine, but I would like to position this drop box exactly below the file name and file mask edit controls, and its label exactly below the labels for these controls.
How can I get the positions of these controls and the corresponding labels (it depends on the Windows version and maybe even on theming, so using the constants that make the dialog look fine on my computer won't do)?
On Vista+, you should be using the IFileDialog, IFileOpenDialog and IFileDialogCustomize interfaces:
Common Item Dialog
Customizing the Dialog
You can use the IFileDialogCustomize::AddText() and IFileDialogCustomize::AddComboBox() methods to add a drop-down list and its label to the dialog, and if needed use the IFileDialogControlEvents::OnItemSelected event to react to the user selecting items in your drop-down list.
However, you cannot decide where custom controls are displayed when customizing this dialog. UI layout is controlled by the dialog itself:
The Common Item Dialog implementation found in Windows Vista provides several advantages over the implementation provided in earlier versions:
...
•Enables simple customization of the dialog, such as setting the label on the OK button, without requiring a hook procedure.
•Supports more extensive customization of the dialog by the addition of a set of data-driven controls that operate without a Win32 dialog template. This customization scheme frees the calling process from UI layout. Since any changes to the dialog design continue to use this data model, the dialog implementation is not tied to the specific current version of the dialog.
...
The only layout access it provides is the order in which you add your custom controls, and any visual grouping. So, you could use IFileDialogCustomize::StartVisualGroup() to create a new group, then call AddText() and AddComboBox() (in that order) to add those controls to the group, and then finally call IFileDialogCustomize::EndVisualGroup().
On the other hand, when using GetOpenFileName() instead, there are some different options for customizing that dialog, and they allow you much finer grain control over the dialog's layout:
Customizing Common Dialog Boxes
Open and Save As Dialog Box Customization
The preferred option is to create a custom dialog box template and specify it in the OPENFILENAME structure. Within the template, you can have whatever controls and layout you want, and then the template can be inserted as a child of a standard Explorer-style dialog, or as a replacement for a standard Old-style dialog. MSDN documents how to custom-position a template within an Explorer-style dialog:
Explorer-Style Custom Templates
To make room for the new controls, the system expands the default dialog box by the width and height of the custom dialog box. By default, all controls from the custom dialog box are positioned below the controls in the default dialog box. However, you can override this default positioning by including a static text control in your custom dialog box template and assigning it the control identifier value of stc32. (This value is defined in the Dlgs.h header file.) In this case, the system uses the control as the point of reference for determining where to position the new controls. All new controls above and to the left of the stc32 control are positioned the same amount above and to the left of the controls in the default dialog box. New controls below and to the right of the stc32 control are positioned below and to the right of the default controls. In general, each new control is positioned so that it has the same position relative to the default controls as it had to the stc32 control. To make room for these new controls, the system adds space to the left, right, bottom, and top of the default dialog box as needed.
The alternative, without using a custom template, is to obtain the dialog's own HWND directly (which can be gotten inside a hook function assigned to the OPENFILENAME::lpfnHook field) and then you have full access to do whatever you want with the dialog. Microsoft assigned fixed control IDs to the standard controls of an Explorer-style dialog (so you must specify the OFN_EXPLORER flag for this approach to work), and those IDs are consistent across Windows versions. Those IDs are meant to be used with the CDM_SETCONTROLTEXT and CDM_HIDECONTROL messages, but they can also be used with GetDlgItem() to get the HWND of certain dialog controls, in this case the cmb13, edt1 and stc3 controls:
cmb13
Drop-down combo box that displays the name of the current file, allows the user to type the name of a file to open, and select a file that has been opened or saved recently. This is for earlier Explorer-compatible applications without hook or dialog template. Compare with edt1.
edt1
Edit control that displays the name of the current file, or allows the user to type the name of the file to open. Compare with cmb13.
stc3
Label for the cmb13 combo box and the edt1 edit control
Once you have those HWNDs, you can manually query their current positions and sizes, add your custom drop-down list underneath them as needed, and resize the dialog's HWND to accommodate your drop-down list.
Whether you use a template or direct HWND manipulation, you would need to use a dialog hook function to process messages from your drop-down list as needed, such as the CBN_SELCHANGE notification.

X11: input focus for popups

For some fun and self-education, I'm tinkering with writing my own X11 toolkit. Here's something that's stumping me.
I have a traditional combo box display element, a typical combo box with a dropdown popup list, like all popular toolkits have.
For the dropdown popup list, I'm creating a new window, a child of the root window, appropriately positioned below the main combo-box display element.
The dropdown popup list is a window in its own full right, that implements keyboard-based navigation, to select the individual entries in the dropdown list.
So, I'm using SetInputFocus to set the input focus to the popup after it opens.
What I find is that when I do that, the window manager then redraws the frame of the main window to indicate that it no longer has input focus. Which is technically true, but I don't see the same results with the more mainstream toolkits, where, in the comparable situation, the main window's frame shows that it still has input focus.
For the pop-up window, in addition to setting override-redirect, I'm also doing everything I can think of, to tell the window manager what's going on: setting the window group leader ID in the popup window's WM_HINTS, setting WM_TRANSIENT_FOR, and setting _NET_WM_WINDOW_TYPE to _NET_WM_WINDOW_TYPE_COMBO; none of that seems to work (I verified that the properties are approriately set, via xprop).
It seems like I have to keep the input focus in the combo box window, and forward keypress and keyrelease events to the display elements in the dropdown popup, which feels clunky. Am I overlooking some property that would tell the window manager that the popup's input focus is linked to the main window's (besides the ones that I've mentioned), that would keep the main window's frame drawn to show that it has input focus, when the input focus is actually in the popup?
Most X11 override-redirect exclusive popup windows (menus, combo boxes, ...) grab the keyboard and/or pointer with either passive or active grab.
See XGrabKey, XGrabKeyboard, XGrabButton, XGrabPointer in the X11 programming manual.
Or maybe don't, because the manual is totally unclear about what the heck these functions are and how they can be used. Search the interwebs for usage examples, probably in other widget libraries. Unfortunately I don't know of a simple informative example offhand.
It is not necessary to call XSetInputFocus at all because all keyboard and/or pointer events are reported to the grabbing clients.

Setting the width of a menu in the Windows API

I'm creating a custom control in wxWidgets that displays a menu as part of it, and currently working on the Windows side of things. wxWidgets doesn't have a way of setting the width of a menu. It just makes the window as wide as the longest string plus a few pixels on either side.
In the API, there is a way to get the actual Windows API menu handle. Does the Windows API have a method of setting the width of a menu other than just calculating it on its own based on the width of the string?
With the handle of the menu, you can cycle through the menu items and call SetMenuItemInfo, indicating that you want to owner-draw the menu items. When you do this, the window that the menu is attached to will receive the WM_MEASUREITEM message, which you would then respond to by setting the dimensions required for the menu. It is here you can set your width.
Of course, this means you have to subclass the windows message handler for the window that contains the menu.
First of all, try to obtain the HWND to the menu:
(1) WM_DRAWITEM (2)get the HDC (3)WindowFromDC(),
then you can arbitrarily adjust aspects of the menu.
NOTE: don't send WM_QUIT WM_CLOSE to the menu, or you'll effectively shut down your computer with no clue.

How do you programmatically change the tab order in a Win32 dialog?

Often time I need to add a control to a dialog after the dialog has been generated via dialog template and CreateDialogIndirect. In these cases the tab order is set by the dialog template and there is no obvious way to change the tab order by including a newly created control.
I recently discovered that you can use SetWindowPos to accomplish this. Determine which control after which you want to insert the new control in the tab order then use SetWindowPos like this:
SetWindowPos(hNewControl, hOldControl, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
This changes the z-order of controls which, in turn, establishes the tab order.
I know this is an old question but here is how to do it at compile time (which is preferable in the vast majority of cases):
http://msdn.microsoft.com/en-us/library/7039hzb0(v=vs.80).aspx
My favourite method:
From the View menu, choose Tab Order.
Choose Assign Interactively.
Double-click the tab order box beside the control you want to be the
first control in the tab order.
Click the tab order box for each of the other controls.
Click anywhere on the form to save your changes and exit Tab Order
mode, or press ESC to exit Tab Order mode without saving your
changes.

Resources