i was studying the example of how to make round-shape form in Visual Basic 6, and i stopped at the code :
Public Const WM_NCLBUTTONDOWN = &HA1
I only know that this is a message to the windows passed as Const ...
What i want to know is :
what is &HA1 ?
what does Const WM_NCLBUTTONDOWN do ? what message does it send to Windows ?
anything else about it .
Please, thanks
You are working with messages that Windows sends to a window to tell your code that something interesting happened. You'll find this constant used in the WndProc() method of a form, the method that runs when Windows sends a message.
The WM_NCLBUTTONDOWN message is one of those messages. WM = Window Message. NC = Non Client, the part of the window that's not the client area, the borders and the title bar. L = Left button, you can figure out BUTTONDOWN.
These messages are declared in a Windows SDK file. You'll have it on your machine, the VS2008 version of that file is located in C:\Program Files\Microsoft SDKs\Windows\v6.0A\Include\WinUser.h. Open it with a text editor or VS to see what's inside. Search for the message identifier to find this line:
#define WM_NCLBUTTONDOWN 0x00A1
The Windows SDK was written to work with C programs. #define is equivalent to Const in VB.NET. The 0x prefix means 'hexadecimal' in the C language, just like &H does in VB.NET. The Windows calculator is helpful to convert hexadecimal values to decimal and back, use View + Programmer. You'll see the reason that &H is used in a VB.NET program, these constants started out in hexadecimal in the core declaration. But Private Const WM_NCLBUTTONDOWN = 161 will work just as well (10 x 16 + 1).
So within WndProc() you'd use a Select Case or If statement to detect the message. And you can do something special when the user clicks the left mouse button on the window title bar. If you ignore it then MyBase.WndProc(m) runs and the normal thing happens: Windows starts a modal loop that lets the user move the window. It is actually very rare that you want to stop or alter that behavior, users are pretty fond of that default behavior since all windows in Windows behave that way. The only message whose behavior you'd typically want to customize is WM_NCHITTEST. Very useful to give a borderless window border-like behavior. But that's another story.
That's a hexadecimal integer literal
It declares a constant; it doesn't actually do anything.
The WM_NCLBUTTONDOWN message is posted when the user presses the left mouse button while the cursor is within the nonclient area of a window. This message is posted to the window that contains the cursor
&HA1 means the hexadecimal number A1, i.e., 161 (though you'll usually see Windows message constants represented in hex). More commonly you'll see this as 0xA1 (or 0x00A1) since that's how the hex number would be represented in C or C++ (the Windows API was originally written for C).
You won't be sending WM_NCLBUTTONDOWN to Windows; it's the other way around. Windows will be sending you WM_NCLBUTTONDOWN.
If you want to know what WM_NCLBUTTONDOWN is for, the documentation is just a Web-search away.
Related
I'm working on a WinUI 3 - C++/winRT - desktop application.
The application displays and updates in a window-sized XAML SwapChainPanel through Direct2D and needs to receive keyboard input from the user. With KeyDown and KeyUp on the SwapChainPanel, I can get raw keyboard input. However, this provides only VirtualKeys, ScanCodes, RepeatCount, etc. through the accompanying KeyRoutedEventArgs.
I can find no way to tell WinUI 3 which keyboard layout to use, nor any sort of keyboard management for such things as shift keys, etc (VirtualKeys are only capital ASCII letters).
What I've managed to do is build window messages from the KeyDowns and KeyUps and send them to TranslateMessage then DispatchMessage so they end up as WM_CHARs in the window's message loop.
This takes care of quite a bit of the shift, caps lock, etc. logic and produces Unicode. However, it doesn't take into account the keyboard layout which, in my case, is Canadian Multilingual with four layers of characters on most keys. I can receive some non-ASCII characters (Latin 1) but they aren't the right ones.
This must be a common situation with all the different languages in the world, but I haven't found anything in the way of a keyboard processing function that would receive raw information from the keyboard, process the control keys and output Unicode.
If the window's message pump is the only way to go (for now ?), how to get TranslateMessage to take into account the keyboard layout ?
Thanks for any help with this.
On a Windows application, I want to check whether the foreground window (of any process) has the text cursor blinking or not.
There seems to be a standard way of doing it using the WinApi function GetGUIThreadInfo, as follows:
(it's C++ code, but the language is not important)
GUITHREADINFO threadInfo = {sizeof(GUITHREADINFO)} ;
GetGUIThreadInfo(NULL,&threadInfo) ;
bool caretState = threadInfo.flags & GUI_CARETBLINKING ; //true if the caret is blinking
This works perfectly for most programs but, unfortunately, not for Google Chrome, whose threadInfo.flags member never has the GUI_CARETBLINKING flag set.
Is there another way of detecting the text caret that works on Google Chrome?
For example, I know that screen readers can traverse Chrome's accessibility tree which exposes the contents of the window to external applications.
Is there, anywhere in this accessibility tree, information relative to the blinking caret?
Edit:
One of the comments made me realize that saying "blinking caret" could be interpreted as if I wanted to literally detect the graphical element known as blinking caret.
That's not my intention. What I'm trying to do is to detect what the blinking caret implies, which is that a text input field is focused.
I want to know the text at a point in for example an Outlook email.
In Excel and Word I am able to get the ActiveWindow. Both object models offer the RangeFromPoint method which I have working.
In Outlook the Applicaion object does have a ActiveWindow but it returns either an Explorer or Inspector object.
Further I tried the following code, however it seems the disabled Word Application object in Outlook does not offer the RangeFromPoint.
Dim ins As Outlook.Inspector = olMail.GetInspector
Dim wDoc As Word.Document = ins.WordEditor
Dim w As Word.Window = wDoc.ActiveWindow
Dim rng As Word.Range = w.RangeFromPoint(mousePosition.X, mousePosition.Y)
I am assuming that Outlook's object model will not help me.
Are there any other methods in the Word Document object model that helps me out?
If the Word Object model does not help must I rely on WinAPI?
If I must use the WinAPI what steps do I need to take?
For example;
Convert Screen point to a window point of the window holding the text (body of the email)
get the text at this point.
What is the best WinAPI to get the text at a point in a Window. Is it to SendMessage with EM_GETSEL?
I tried a few things here.
Why I want to know the text at a point.
I am building custom tooltips into office. When the mouse hovers over a point (through the use of the winapi function TrackMouseEvent) I receive from Windows the point where the mouse is. I then need to know in Outlook (Explorer / Inspector) what the mouse is over.
First Thought - Outlook and Word Object Model alone.
As you can see in the question my first thought was to use the same Window object you can use in Word and implement the RangeFromPoint method. But MS decided to not support this in Outlook. So this is a dead end.
The second option here was to use either or both of these
Selection.Information(Word.WdInformation.wdHorizontalPositionRelativeToPage)
Selection.Information(Word.WdInformation.wdVerticalPositionRelativeToPage)
and / or
Selection.Information(Word.WdInformation.wdHorizontalPositionRelativeToTextBoundary)
Selection.Information(Word.WdInformation.wdVerticalPositionRelativeToTextBoundary)
Vertical relative to page always returned -1 even when the text was clearly in view.
The Relative to Text Boundary returned numbers and they changed with positions but I did not work out where the Boundary was when in the Outlook Inspector. Margins did not help me. This could be a way to do this but i did not work it out.
IUIAutomation or Automation
I have no experience with these however my attempts to get the TextPattern failed on Outlook 2007 and Outlook 2010. I name these versions because I found questions here reporting that they were successful with 2013. I think MS at the time intentionally tried to hide the body of the email to stop ummm slow down email viruses.
WinApi
The text body of the email is in a window of Class _WwG and the contents of the window is not visible. You get "message" as the text. Seems here too MS did this intentionally. Thus trying to get the text at a position is not going to work.
Combination of WinApi and Word Object Model
The solution that I found which works with the Explorer reading panes and with all inspectors is to use a combination of the WinApi and Word.
Receive a mouse hover event with point in a window (_WwG Class for Outlook)
Use SendMessage and send a messsage to this window with the WM_LBUTTONDOWN flag.
Get the Word Document from the Inspector.WordEditor method.
The current Range selected will be where the mouse is located in the text.
Expand the range to the word or whatever you need and now you have what is under your mouse.
For read only windows in Outlook there is no caret visible to the user but it still exists and can be found and used.
I have not implemented this on Outlook items that are being drafted (Cursor is in use and visible), but I suppose I will have to move the selection to the mouse position and then move it back to be able to implement it. I could imagine this is not the best for some users.
Edit
There is one issue with this that I could not solve. By sending a click to the window, you click on what is at that point. If there is a hyperlink there, which is the case with email addresses in a mailItem then it follows the hyperlink. I could not work around this issue properly. The only thing I did find in the WinProc was that when the mouse is over a hyperlink then Outlook shows a tooltip and there is a WM_USER + 2 message. Listen for this message and do not click if this message is received.
I wonder if there is any way to somehow interact with windows that are currently open on a Windows system. I am interested in getting some of their properties, namely:
Location
Dimension
is in background?
possibly window title
Preferably, I would like to do that in Java but any suggestions are welcome.
A comment by theB linked to good resources for Java. I'll run through the relevant Windows APIs, in case you want to go native with C++.
To enumerate all the top-level windows in the system, use EnumWindows. You give it a callback function with the signature of EnumWindowsProc, so it will receive each window handle as the first parameter.
You can get the window location (in screen coordinates) and dimensions with the GetWindowRect function. Pass in the window handle you received and get an LPRECT (pointer to RECT) out.
To determine whether a window is maximized, use GetWindowPlacement and check the showCmd field of the WINDOWPLACEMENT structure you receive.
Finally, to get a window's caption, use GetWindowText. (As an aside, if you want to get the text of a control in another process, you'll need to send the WM_GETTEXT message yourself.)
I have a third-party GUI program that I'm wrapping with a Python class (using ctypes).
Are there Win32 API functions that can do the following?
1) Obtain the window handle for a window at a given screen location.
2) Obtain the window handle for a Button or Static window with a given caption.
3) Send text to an Edit window.
4) Extract text from a RICHEDIT instance.
I have WinSpy (a Spy++-type app) and know that it's possible to obtain window handles and captions using that tool, but I need something that works within Python.
I assume that Python's ctypes gives me access to any function within the Win32 API, so I've been scanning MSDN (especially this windows/messages section). I can't seem to find anything that works.
Thanks,
Mike
WindowFromPoint
FindWindowEx to find a child of a window with a given class and name (caption). Repeat operation to get through each parent-child indirection. EnumChildWindows can be helpful too.
SendMessageTimeout + WM_SETTEXT
SendMessageTimeout + WM_GETTEXT or EM_STREAMOUT
I had trouble finding a very simple example for WM_GETTEXT with pywin32 and figured here might be a good place to add one, since it answers part of the question:
MAX_LENGTH = 1024
handle = # A handle returned from FindWindowEx, for example
buffer = win32gui.PyMakeBuffer(MAX_LENGTH)
length = win32gui.SendMessage(handle, win32con.WM_GETTEXT, MAX_LENGTH, buffer)
result = buffer[:length]