There is an edit box in some dialog in my application, which is running on Windows XP. When I issue EM_GETLINE on this control, it returns its contents and it's ok, but when I start Spy++ the control suddenly starts behaving incorreclty and always returns an empty string. What might be a problem?
The problem was in a buffer size. Win200 thinks that 1 byte is good enough to return the text inside the control, but WinXP thinks that the buffer must be at least two bytes long.
Related
Explorer seems to always start my application with SW_MAXIMIZE (STARTF_USESHOWWINDOW is set in STARTUPINFO.dwFlags). I know that ShowWindow will use this value the first time you/Windows needs to display a window but it has the unfortunate consequence of maximizing a window that should never be maximized.
My window is created with CreateDialogIndirectParam and has the following styles: WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_CLIPCHILDREN|DS_MODALFRAME|DS_CENTER|WS_VISIBLE. Why does ShowWindow not check if WS_MAXIMIZEBOX is set before allowing STARTF_USESHOWWINDOW to force SW_MAXIMIZE? Is this a bug in Windows?
This happens on a HP Stream 7 with Windows 8.1. I'm not sure if Explorer does this because it is touch enabled or because of the small screen.
Is this Explorer behavior documented anywhere and is there a way to turn it off? What is the best way to stop Explorer (or any other parent process) from affecting my initial window mode? (I don't want to block people starting me with SW_*MINIMIZE*)
WinVer.exe in system32 has the same problem:
My first thought was to turn off STARTF_USESHOWWINDOW in the PEB if the parent wanted me to start maximized but that is too nasty and undocumented so I have not tried that yet.
Preventing any kind of size change (which is OK for my application since it is just a "modal" dialog) sort of works:
case WM_WINDOWPOSCHANGING:
((WINDOWPOS*)lp)->flags |= SWP_NOSIZE;
return true;
The problem is that the window position is still set to 0 x 0 like a maximized window.
A better solution seems to be to detect and correct the problem after WM_INITDIALOG:
case WM_INITDIALOG:
PostMessage(hDlg, WM_APP, 0, 0);
break;
case WM_APP:
if (IsZoomed(hDlg)) ShowWindow(hDlg, SW_SHOWNOACTIVATE);
break;
I am the proud owner of several HP Stream 7 tablets and I would like to add my 2 cents here. Microsoft has made an arbitrary decision that devices with screen sizes smaller than 8 inches will behave differently than the norm. A lot of users are somewhat aware of this, but unaware that this is where your problem originates.
Windows determines a screen's size by reading the EDID information from the screen, which contains sizing information in it, in centimeters.
If no sizing information is present in the EDID, or the sizing information is below Microsoft's arbitrarily chosen 8 inch threshold, you get this apparent misbehavior which is at the very least, aggrivating to those who notice it and don't want it.
The solution is to override the default driver for the monitor in Device Manager with one that informs Windows that the screen is in fact, 8 inches or larger.
To do so, you need to first read the EDID information from the registry with a tool such as Deltacast's E-EDID Editor (free, last time I checked), and modify the size values and save the modified file someplace you can find it.
After you have modified your EDID file and saved it, download Monitor Asset Manager from EnTech (also free) and use it to create an INF file.
Once the INF file has been created, you need to restart Windows with the Advanced settings menu and choose to Disable Driver Signing Enforcement, since the INF file you created won't be digitally signed. Once disabled, open Device Manager in Windows and update the driver for the monitor using the INF file you created. You will need to confirm that you do in fact want to install the unsigned driver file.
Reboot and Windows will now behave normally with the one catch that, the onscreen keyboard will now appear a different size and will have more options available.
Sadly, Microsoft can change this behavior in the future, so there is no guarantee that through the same flawed decision making process they used to implement this in the first place, they won't force it down our throats again, using a much more difficult to counteract method.
I am working with an edit control in a dialog--all MFC. The only style specified in the resource is ES_AUTOHSCROLL. The dialog comes up and displays correctly. The edit control also works and edits text correctly--up until a point. At that point, it stops displaying text completely. The edit control is just blank.
My first thought was to try and adjust the limits of the edit control by sending calling SetLimitText() on the edit control which just sends EM_SETLIMITTEXT. I set a big number which was 10x the previous limit, and verified by EM_GETLIMITTEXT that the number retrieved is equal to the number set. After that, I still have the problem and nothing is changed.
Next I tried trapping EN_MAXTEXT and EN_ERRSPACE. Neither one of those notifications was sent.
Lastly, I started trying a little different input, and if I entered a space or a period then I could get a few more characters displayed than if I entered a W. The font in the dialog is MS Shell Dlg which on my system maps to Microsoft Sans Serif. It's a proportional font, do different characters have different widths, so I was beginning to thing that maybe it was GDI related.
Next, I trapped EN_CHANGE, and when it is fired off, I went and created an IC for the display, selected the font into the IC from the edit control, and then called GetTextExtent() on the text in the edit control. The problems occur in display right around 32760 which is darn near the 16-bit signed integer limit.
So, I am thinking that my problem is GDI related in that the EDIT control cannot draw past that limit. I tried substituting a RICHEDIT2 control, but it displayed fewer characters before going blank.
The other weird thing is that if I keep on entering characters and call GetWindowText() on the edit control, all the characters will be returned. It is just that the edit control is blank.
Yeah, maybe I shouldn't be displaying that many characters, but it is what it is.
Does anybody have a better explanation, solution, or workaround?
This could very well be another silly question, but I can't seem to find the answer (or any for that matter), so here goes.
I have a command line program that uses SIGWINCH on Linux to detect the window size change, and I apparently have a user who is using the program on Windows. The problem, is that the program uses SIGWINCH to detect changes in the window size and this signal is unsupported on Windows. I've tried Googling for every combination of search terms I can think of, but due to the relationship between SIGWINCH and changes in the size of the window, I'm having trouble finding any useful results. I'm looking for a Windows equivalent, or the method most often used to detect changes in the window size on Windows computers.
How do you detect changes in window size on Windows?
Since I don't think you can subclass console windows (and thus catch WM_SIZE messages), you may just have to poll GetConsoleScreenBufferInfo.
EDIT: Upon further investigation (not tested!), it might also be doable without polling using ReadConsoleInput. Summary: Call SetConsoleMode to turn on window input events. From a different thread, wait for the console input handle to become signaled using WaitForSingleObject or a similar function. Read all pending console events; the presence of window buffer size events means something's resized your console window.
I am writing an app with raw windows API (opensource Win32++) where I have a ListView.
The problem I have now is that whenever an item in the ListView is clicked, the system/app will generate a warning tone/sound "ding". Furthermore, I noticed I cannot get the LVN_ITEMACTIVATE through item-dbl-click or item-keypress-enter, which would normally work if this problem had not occur.
Would anyone have any idea how this might be happening?
I believe there is nothing wrong with Win32++, it just could be one of the things I do is causing this. But my program has become quite big to dissect plus I have no idea where to start looking.
Thanks.
PS: I had my computer muted for the longest time, hence, I don't know when this started eventhough I had the listview since a long time ago. T_T
Start looking with a tool that can show you the Windows messages that the control generates and receives. Like Microsoft's Spy++. Compare it with a working list view to have an idea what might be amiss. Also check the parent window. I haven't otherwise heard of listviews that dingaling, the LVN_ACTIVATEITEM should fire the first WM_LBUTTONDOWN, no double-click necessary.
I have the following (minor) problem that I want to solve programmatically. Whenever I unplug my secondary monitor from my laptop, every windows get moved to be visible in the now smaller resolution. When I plug my external monitor back in, I need to manually replace the windows to their correct position. I have to do that every morning (sigh).
Now I decided to write a simple command-line program that could save the position of every open windows and reposition them when I want to restore their positions.
I have managed to do something that works just fine by using the Accessibility API, which allows me to control windows that aren't part of my process space. I have a problem though: the program can only see the windows that are in my current space (I'm talking about the OSX Spaces feature here).
In other words, when I run my program to save the windows positions, it will only be able to save the positions of the windows in the space I'm currently in.
Some more details about my program:
It loops through all the processes running and get their PIDs.
It creates application elements from these PIDs (AXUIElementCreateApplication)
It gets the windows associated with this application, and then their positions
When getting the windows elements from the application element, the AXUIElementCopyAttributeValues only returns me the windows of the current space.
Now, is there a way to control any windows (across different spaces)? If not, I wouldn't mind programmatically changing spaces to get every windows, but that doesn't seem possible.
Any help would be appreciated!
I'm not aware of a documented way to switch spaces.
You probably want CGSPrivate.h - CGSSetWorkspace et al. Just keep in mind those functions are SPI and can break without warning even in a 10.6.x release.
If you want to avoid using private APIs you can take advantage of the fact Mission Control has keyboard shortcuts for moving to various spaces, and you can programmatically send the key codes to activate them. I wrote a blog post about it (http://ianyh.com/blog/2013/06/05/accessibility/) for a tiling window manager I've been working on called Amethyst, which has some example code you can check out in -[AMWindow moveToSpace:].
The short version is moving to a space looks something like using the default ctrl + arrow key to move to adjacent spaces:
CGEventRef keyboardDownEvent = CGEventCreateKeyboardEvent(NULL, kVK_RightArrow, true);
CGEventRef keyboardUpEvent = CGEventCreateKeyboardEvent(NULL, kVK_RightArrow, false);
CGEventSetFlags(keyboardDownEvent, kCGEventFlagMaskControl);
CGEventSetFlags(keyboardUpEvent, 0);
CGEventPost(kCGHIDEventTap, keyboardDownEvent);
CGEventPost(kCGHIDEventTap, keyboardUpEvent);
CFRelease(keyboardEvent);
CFRelease(keyboardEventUp);
You could combine this with NSWorkspaceActiveSpaceDidChangeNotification to traverse all spaces and gather window data.
Also, as a potentially interesting note the accessibility APIs can actually give you windows across all spaces at the same time, but it will only give you windows in spaces that you have traversed to since the process utilizing the APIs launched. I have no idea why this is the case, but it does seem to be.