Show UltraMessageBox in the same screen during multi monitor scenario - infragistics

I am trying to display a UltraMessageBox and it works fine when I use a single monitor, but If I open my application to second monitor, the message box is hiding behind other opened applications in the 1st monitor.
Is there any setting I can set the UltraMessageBoxManager so that the opened message box shows in the same monitor as the application?

There are two essential properties in UltraMessageBoxInfo class that allows you to position the message box wherever you want, if there is even more than one monitor.
StartLocation
Specify the start-up location of the message box. This
value is taken under consideration only when StartPosition property is
set to Manual.
StartPosition
Specify the initial position of the dialog. If the enumeration is set
to Manual, then the location of the form is determined by the
StartLocation property.
More information about how to setup StartPosition and StartLocation with code snippet is available at https://www.infragistics.com/help/winforms/winmessageboxmanager-setting-up-the-startposition-and-startlocation-properties

Related

Is there an event mask I can set in Xlib to receive an event whenever a window title is changes

I'm writing a window manager in C++ (mostly c stuff but i need unordered_map) with Xlib and my current approach to updating window titles is to get window titles whenever it receives any unrelated event. The problem with this is that if I open XTerm, for example, the titlebar says "xterm" until I do something that sends an event (like clicking the titlebar) and then the window title changes to "username#hostname:WD". It's supposed to update to that format after showing "xterm" for only a split second. It's also supposed to change every time you use the cd command.
Is there an event mask I can use to do this? I looked in a list of Xlib event masks and couldn't find an event mask that does this.
The client should set _NET_WM_NAME application window property. If you want to get events when application updates this property you can set PropertyChangeMask on the application window. Mask value is 0x400000.

Is there a notification code when cursor position changes in Edit Control MFC?

Is there a notification code sent when the cursor position changes in an Edit Control MFC? I want to display the cursor (character) position for the user
There is no EN_... notification sent by the Edit control itself when the caret position changes.
However, you can use SetWinEventHook() to register for EVENT_OBJECT_LOCATIONCHANGE notifications for your app's process ID and UI thread ID.
EVENT_OBJECT_LOCATIONCHANGE
0x800B
An object has changed location, shape, or size. The system sends this event for the following user interface elements: caret and window objects. Server applications send this event for their accessible objects.
You can then have your callback function filter the notifications by checking if the provided hwnd is your Edit control and the provided idObject is OBJID_CARET.
OBJID_CARET
The text insertion bar (caret) in the window.
When detected, you can get the actual caret position by sending an EM_GETSEL message to the Edit control.
Gets the starting and ending character positions (in TCHARs) of the current selection in an edit control.
Or, if you are using the CEdit class, use its GetSel() method.
Call this function to get the starting and ending character positions of the current selection (if any) in an edit control, using either the return value or the parameters.

SetCursor while dragging files into a window

I'm using windows API to create an application with a window only, so everything inside this window is drawn using Direct2D.
Now I want to drop some files in specific parts of my window's client area, and I'm handling the message WM_DROPFILES. No problem here, when the files are dropped in those specific areas, I can treat them correctly and everything is working properly. BTW, my window is DragAcceptFiles(hWnd, true), it always accepts drag/drops.
I want the mouse cursor to be different depending on the area of the window the mouse is in. In the areas that I don't treat the drop, I want the cursor to be the invalid icon, and for the areas of the window that I do handle the drops, I want the correct drop icon.
The first thing I noticed is that no message is generated when files are being dragged into the window, and for this reason I added a mouse hook (WH_MOUSE_LL using SetWindowsHookEx). When the hook is processed, I only look at the WM_MOUSEMOVE message, so I can change the cursor according to the area the mouse is in.
The problem is that the SetCursor does nothing, if my windows is configured to accept drag files, the cursor is always the drag/drop cursor, no matter how many times I call SetCursor.
It seems impossible to change the cursor this way, but is there any other way of doing what I'm trying to achieve?
You need to write a class in your code that implements the IDropTarget interface, then create an instance of that class and pass it to RegisterDragDrop() to associate it with your window. Do not use DragAcceptFiles() anymore.
Whenever the user drags anything (not just files) over your window, your IDropTarget::DragEnter() and IDropTarget::DragOver(), IDropTarget::DragLeave() methods will be called accordingly, giving you the current coordinates of the drag and information about the data being dragged (so you can filter out any data you don't want to accept). If you choose to accept the data, and the user actually drops the data onto your window, your IDropTarget::Drop() method will be called.
As the drop target, it is not your responsibility to change the cursor. It is the responsibility of the drop source instead to handle that as needed. In your IDropTarget::DragEnter() and IDropTarget::DragOver() implementations, all you need to do is set the pdwEffect output parameter to an appropriate DROPEFFECT value. That value gets passed back to the drop source, which then displays visual feedback to the user (like changing the cursor) in its IDropSource::GiveFeedback() implementation.
It is possible for your IDropTarget to be invoked without user interaction (ie, programmably from another apps, and not just for drag&drop operations). That is why the drop source, not the drop target, decides whether or not to display UI updates to the user, since only the drop source knows why it is invoking your IDropTarget in the first place. The drop target does not know (or care) why it is being invoked, only that it is being given some data and asked whether it will accept or reject that data, nothing more.
Refer to MSDN for more details:
OLE and Data Transfer
Transferring Shell Objects with Drag-and-Drop and the Clipboard

how to find where a mouse event come from?

Is there any way to figure out where did a mouse event come from?
I mean, if I code a C/C++ program on Windows, and get a mouse click event on it, how can I find if this event come from a mouse driver, a touchpad, or if it was send by an application (mouse event simulation by sending appropriate message like WM_LBUTTONDOWN).
Thanks for any help :)
This is not possible for an application in user mode - mouse events generally don't provide documented info on event source. There is the way to obtain some message extra info by Win32 API function GetMessageExtraInfo but there is no safe way to interpret this data. It is very device specific, undocumented and never guaranteed to ever present.
To solve this task you need to develop your own Mouse Filter driver basing on Windows DDK sample.
Its callback has input parameter MOUSE_INPUT_DATA - structure containing mouse event info. There is the field UnitId:
UnitId Specifies the unit number of the mouse device. A mouse device name has the format \Device\PointerPortN, where the suffix N is the unit number of the device. For example, a device, whose name is \Device\PointerPort0, has a unit number of zero, and a device, whose name is \Device\PointerPort1, has a unit number of one.
GetAsyncKeyState function can be used to check if the button was pressed, and unfortunately SendInput cannot trick this function.
So you can simulate a mouse click, but the program can check if the button was really pressed.
So creating your own mouse driver is better.
I needed a safe way so simulate mouse/keyboard behavior for my bot, and I wrote a detailled article on my blog http://poker-botting.blogspot.fr/2012/11/how-to-simulate-mouse-and-keyboard.html

How do I control the text input panel programmatically (TabTip.exe) in Windows Vista/7

I'm adapting an application for touch screen interface and we want to use the tablet text input panel included in Windows Vista/7, specifically its keyboard. I want to show and hide it as appropriate for my app. Basically I want ShowKeyboard() and HideKeyboard() functions. What's the best way to control this?
I looked at the ITextInputPanel API but I was unable to control the keyboard directly with it (maybe I missed something?). I have also unsuccessfully tried to send window messages to its window.
The application is written in C++/MFC.
Any pointers at all are greatly appreciated.
I solved the problem. It turns out that Spy++ really is a Windows programmers best friend.
First, the window class of the input panel window turns out to be "IPTip_Main_Window". I use this to get the window handle like so:
HWND wKB = ::FindWindow(_TEXT("IPTip_Main_Window"), NULL);
It turns out that I can just post the same WM_COMMAND messages that its own menu is sending. Most of the operations are available from the menu: dock top, dock bottom and float. The code for sending those messages are:
::PostMessage(wKB, WM_COMMAND, MAKEWPARAM(X,0) , 0);
where X is 10021 for dock bottom, 10023 for dock top and 10020 for floating. The 0 in the high word indicates that the message is sent from a menu.
Finally, I wanted to be able to show and hide the input panel. I noticed that I could turn on a desk band which only includes a single button for toggling the visibility of the input panel. Spy++ing on the messages posted from this button revealed that it sends a global registered window message which is named "TabletInputPanelDeskBandClicked".
Sending this message to the input panel causes it to toggle its visibility.
The HideKeyboard() function now looks like this:
DWORD WM_DESKBAND_CLICKED =
::RegisterWindowMessage(_TEXT("TabletInputPanelDeskBandClicked"));
void HideKeyboard()
{
HWND wKB = ::FindWindow(_TEXT("IPTip_Main_Window"), NULL);
if(wKB != NULL && ::IsWindowVisible(wKB))
{
::PostMessage(wKB, WM_DESKBAND_CLICKED, 0, 0);
}
}
The ShowWindow() function is implemented similarly, but it will also start the keyboard if it is not running.
Update:
It seems that this inter-process messaging is disallowed in Windows Vista/7. When running this command in a non-elevated process it will fail with "access denied". My guess is that this is caused by User Interface Process Isolation (UIPI) protection found in Windows Vista/7. Since the Tablet PC Input Panel is running as a child process of a service it has higher integrity level than user programs, and thus cannot be sent any (or a very limited set of) messages to.
Update:
It turns out that the Tablet PC Input Panel is indeed running in high integrity level, whereas processes started by a limited user account is medium integrity level.
For Windows 8:
Note: Just like the Windows 7 solution, this requires an elevated process.
The input panel is not a descendant of HWND_DESKTOP. (It's probably some kind of Metro window.) In order to get the window handle, do a series of horizontal sweeps in a grid-like pattern testing with WindowFromPoint(). For each test, check the window class of the parent window to see if it is "IPTip_Main_Window".
To show the input panel, launch "C:\\Program Files\\Common Files\\microsoft shared\\ink\\tabtip.exe". To determine if it is already in docked mode, read registry key:
HKEY_CURRENT_USER\Software\Microsoft\TabletTip\1.7\EdgeTargetDockedState
A value of 0 indicates the input panel is in floating mode. If that was the case, post the following message to toggle the docked state:
DWORD WM_DOCK_BUTTON_PRESSED = ::RegisterWindowMessage(_TEXT("IPTipDockButtonPressed"));
PostMessage(hwndInputPanel, WM_DOCK_BUTTON_PRESSED, 0, 0);
To hide the keyboard, post the following:
PostMessage(hwndInputPanel, WM_SYSCOMMAND, SC_CLOSE, 0);