First and last window don't show up - c++

I'm creating a WinApi application for my programming course. The program is supposed to show an LED clock using a separate window for each 'block'. I have figured most of it out, except for one thing: when creating the two-dimensional array of windows, the first and last window never show up. Here's the piece of code from the InitInstance function:
for (int x=0;x<8;x++)
for (int y=0;y<7;y++) {
digitWnd[x][y] = CreateWindowEx((WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_NOACTIVATE | WS_EX_STATICEDGE),
szWindowClass, szTitle, (WS_POPUP| WS_BORDER), NULL, NULL, NULL, NULL, dummyWnd, NULL, hInstance, NULL);
ShowWindow(digitWnd[x][y], nCmdShow);
UpdateWindow(digitWnd[x][y]);
}
The same loop bounds are used everytime I interact with the windows (set position and enable/disable). All the windows seem to be working fine, except for digitWnd[0][0] and digitWnd[7][6]... Any ideas as to what is happening?

Open Spy++ and check if the missing windows are really missing or just overlapped by other windows. It's possible that you have some small error in the position calculations code that puts them behind another window or outside of the screen.

To validate your creation mechanism I would check:
the array initialisation HWND digitWnd[8][7]
if the parent window dummyWnd is valid
the return value of CreateWindowEx() != NULL
Another point which comes to my mind is, that you create windows with dimension 0 - no width or height. So maybe it would be a good idea to set the size within CreateWindowEx(...)

Is this your first call to ShowWindow()? If so, according to MSDN, "nCmdShow: [in] Specifies how the window is to be shown. This parameter is ignored the first time an application calls ShowWindow". This could mean that you can fix your program by simply calling ShowWindow() twice. Give it a try and see if it works. Other than that, you'll probably have to provide more of the code for us to look at.

Related

Start chromium browser in minimized state (Win32/WinAPI)

I want to start browser in minimized state, however in this list there's no option for minimizing. So I thought of using ShowWindow() but some issues arise. I don't know how to use EnumWindows() or its derivatives. Only alternative I know is GetWindow() but I'm not sure of the position of window at Z-order. This is my solution:
HWND hwnd,hwnd2; //hwnd is my application's top level window
char t[128];
std::string t2;
for(int i=0; i<128&&t2!="found"; i++)
{
if(!i||i==64) hwnd2=hwnd; //turn direction
hwnd2=GetWindow(hwnd2,i<64?2:3); //loop backwards and forwards
GetWindowText(hwnd2,t,GetWindowTextLength(hwnd2)+1);
t2=t; if(t2.find("New")!=-1) t2="Found"; //Default title is "New Tab..."
}
ShowWindow(hwnd2,SW_MINIMIZE);
Assuming there won't be more than 128 windows, it works fine but since a window takes ~2 seconds to open, at the time ShowWindow() occurs, the window is not yet ready. So I used a timer for it.
SetTimer(hwnd,1,2000,0);
and
case WM_TIMER:
KillTimer(hwnd,1);
ShowWindow(hwnd2,SW_MINIMIZE);
break;
But it's impossible to know the exact time so the window gets minimized after it's shown for some milliseconds. I tried setting multiple timers in an interval of 50ms.
for(int i=0; i<50; i++) SetTimer(hwnd,1+i,i*50,0);
and
case WM_TIMER:
KillTimer(hwnd,wParam);
ShowWindow(hwnd2,SW_MINIMIZE);
break;
It usually minimizes window before it's shown, not always though. Also it changes the cursor to busy state every 50ms. Is there a way to stop this when the minimizing successfully performed once? It's not possible to determine this from the return value of ShowWindow() so is there a way? How can minimizing window before it's shown be guaranteed? Can I somehow make it wait till browser window is ready then sending ShowWindow() on the right time at once? How can I improve my solution into an easier one?
WinExec gives you very little control over spawned process.
Use CreateProcess, and set LPSTARTUPINFOA lpStartupInfo's WORD wShowWindow; to SW_MINIMIZE
Make sure that dwFlags contains STARTF_USESHOWWINDOW
Here is how to use it:
#include <windows.h>
int main()
{
PROCESS_INFORMATION processInformation = { 0 };
STARTUPINFO startupInfo = { sizeof STARTUPINFO };
startupInfo.dwFlags = STARTF_USESHOWWINDOW;
startupInfo.wShowWindow = SW_MINIMIZE;
wchar_t cmd[] = L"C:\\Program Files\\Internet Explorer\\iexplore.exe";
// Create the process
BOOL result = CreateProcess(NULL,
cmd, // command line
NULL, // process security attributes
NULL, // primary thread security attributes
FALSE, // handles are not inherited
NORMAL_PRIORITY_CLASS |
CREATE_NO_WINDOW, // creation flags
NULL, // use parent's environment
NULL, // use parent's current directory
&startupInfo, // STARTUPINFO pointer
&processInformation); // receives PROCESS_INFORMATION
}
UPDATE
In the referenced doc, they state:
the wShowWindow member is used if the nCmdShow parameter of ShowWindow is set to SW_SHOWDEFAULT.
There is similar comment on the position and size field.
Apparently, some application do NOT use the defaults. For example, chrome and calc open their window at the position it was closed previously.
You can find that stored location in the Registry and update it.
More info
Google Chrome default opening position and size suggests to edit Preferences file. It looks like this:
"window_placement":{"bottom":1363,"left":406,"maximized":false,"right":1356,"top":217,"visible":false,"work_area_bottom":1400,"work_area_left":0,"work_area_right":2560,"work_area_top":0}
I've tried to invent keys like minimized, hidden, visible - no luck :)
You could shift the window off-screen; I have partial success - chrome moves it back in so at least a few pixels show...

GetWindowText() error 1400

I'm trying to get the current active window name with the code below :
HWND winHandle = GetActiveWindow();
wchar_t buffer[512] = L"";
int getT = GetWindowText(winHandle, (LPTSTR) buffer, 511);
When used on the window of the program, I get the window name correctly, otherwise, I'm getting error 1400. What could be the problem ?
Thanks
Error 1400 is ERROR_INVALID_WINDOW_HANDLE according to Microsoft's documentation. This means an invalid HWND is being passed to GetWindowText.
Working backwards, this means GetActiveWindow didn't return a valid handle, probably NULL instead. According to a comment on the documentation for GetActiveWindow this will happen when the active window doesn't belong to the current application or thread.

How to disable a secondary monitor (with ChangeDisplaySettingsEx)?

I'm trying to follow the instructions on MSDN given here to disable a secondary monitor.
I'm trying to use specifically this set of functions to allow compatibility with older versions of Windows.
However, I can't manage to disable a monitor. I'm running and testing this on Windows 7 x64.
All I get is a flickering screen. The code definitely detects the monitor properly - I managed to change resolution and view it's display modes easily.
Here are (parts) of my code - I tried a lot of variations on the fields for DEVMODE
DEVMODE deleteScreenMode;
ZeroMemory(&deleteScreenMode, sizeof(DEVMODE));
deleteScreenMode.dmSize = sizeof(DEVMODE);
deleteScreenMode.dmDriverExtra = 0;
deleteScreenMode.dmFields = DM_POSITION | DM_PELSHEIGHT | DM_PELSWIDTH;
deleteScreenMode.dmPelsWidth = 0;
deleteScreenMode.dmPelsHeight = 0;
POINTL delete;
deleteion.x=0;
deleteion.y=0;
deleteScreenMode.dmPosition = deleteion;
LONG result = ChangeDisplaySettingsEx(devName,
&deleteScreenMode,
NULL,
CDS_UPDATEREGISTRY,
NULL);
Does anyone have experience with this? Thanks
I've decided to advance into a different problem - setting a primary display - and by pure luck I've stumbled into the solution.
There are 2 conditions to disable a monitor that aren't specified anywhere:
1) You can't disable the monitor dynamically - you must use CDS_UPDATEREGISTRY to write it into the registry.
2) More importantly, for some weird reason, you must first store the change in the registry (with or without CDS_NORESET, it doesn't matter), and then use again ChangeDisplaySettingsEx with NULL values to make the changes happen. This might have something to do both monitors connected to the same display device, I'm not sure...
Anyway here is the code that worked for me:
result = ChangeDisplaySettingsEx(devName, &deleteScreenMode,
NULL,
CDS_UPDATEREGISTRY | CDS_NORESET ,
NULL);
ChangeDisplaySettingsEx (NULL, NULL, NULL, NULL, NULL);
Hope it'll help someone somewhere someday.
A similar solution is hinted at here:
http://support.microsoft.com/kb/308216
This works for attaching screens. However, even armed with that knowledge, the ChangeDisplaySettingsEx documentation on how to detach a screen is also wrong about the DevMode fields that need to be set. As you noticed, you have to set not only DM_POSITION, but also DM_PELSHEIGHT | DM_PELSWIDTH.
In Windows 7 there's a new SetDisplayConfig API, but I have no personal experience with it yet. Hopefully it's better documented!

Holding scroll-bar gets command prompt to pause in Windows

I have a program where I record data through an ADC system from National Instruments (NI).
The device buffers information for some time, and then the program collects the buffer data at some point. If the program collects data larger than the buffer, then the buffer would have to free without my program receiving the data, which will cause the NI library to throw an exception saying that requested data isn't available anymore, since it was lost.
Since my program is a command-prompt program, if the user clicks and holds the scrollbar, the program pauses, which could get this problem to happen.
How can I get over this problem without increasing the buffer size? Can I disable this holding thing in Windows?
Thanks.
Only the thread that is attempting to output to the console is blocked. Make this a separate thread, and your problem goes away.
Of course, you'll need to buffer up your output, and do something sensible if the buffer overflows.
For reference, here's the simple code I used to test this, you will note that the counter continues to increase even when the scroll bar is held down:
#include <Windows.h>
#include <stdio.h>
volatile int n = 0;
DWORD WINAPI my_thread(LPVOID parameter)
{
for (;;)
{
n = n + 1;
Sleep(800);
}
}
int main(int argc, char ** argv)
{
if (!CreateThread(NULL, 0, my_thread, NULL, 0, NULL))
{
printf("Error %u from CreateThread\n", GetLastError());
return 0;
}
for (;;)
{
printf("Hello! We're at %u\n", n);
Sleep(1000);
}
return 0;
}
Whilst there may be ways to bypass each individual problem you can possibly conceive with the output [including for example running it over a network on a sometimes slow output link, or some such], I think the correct thing to do is to disconnect your output from your collecting of data. It shouldn't be hard to do this by adding a separate thread that collects the data, and having the main thread display to the command prompt window. That way, not matter which variation of "output is blocked" Windows throws at you, it will work - at least until you run out of RAM, but tat that point it's YOUR program's decision to do something [e.g. throw away some data or some such].
This is generally how the problem "I need to collect something, and I also need to allow users to view the data, but I don't want the two to interfere with each other" is solved.
First use the GetConsoleWindow winapi function and get the HWND of your console.
now i suggest two ways to do this,
Method I
Subclass the window by creating your own WindowProcedure. (get help from here)
Now that you have subclassed it, you can intercept the WM_VSCROLL and WM_HSCROLL messages and do your own remedy to your code.
Method II
Change the size of the window using some function like SetWindowPos so that the scroll bars are not needed.
or Change the size of the console screen buffer so that the scroll bars are not needed.
Method I has lot of control over the application, but its a little bit complex than the method II which is very simple.
If you want to forbid the user from resizing the console window, just remove the WS_THICKFRAME from the WindowStyle of the console window.
I was in a similar situation and found that this kind of blocking behaviour could be caused by the quick edit "feature" of the command prompt. This question explains about it and the answer shows how to disable it. Hope that helps, even after some years :)

How to trigger "running state" in Flash Player?

If I use windowed activation (giving a valid HWND to the Flash PLayer in the GetWindow function is enough to trigger this), the player will run the loaded swf file. However, if I use windowless activation, the loaded file does not run, only the very first frame is displayed. This article claims that I'm supposed to call
DoVerb(OLEIVERB_SHOW, NULL, (IOleClientSite *)this, 0, NULL, NULL);
However, this does not have any effect. What am I doing wrong?
Edit: Since I made this post, I found out that it returns -2147467259, which is not a known HRESULT, but certainly not 0. What does it mean?
After some more digging I found out that the return value is OLE_E_NOTRUNNING.
I have found the problem. Before this call, I was doing:
hr = _shockwaveFlash->put_WMode(BSTR("opaque"));
BUT I blatantly ignored the HRESULT there. It made the Flash Player confused, because it is not a valid way to insert a BSTR constant in the code (which is a wide string). Correctly:
hr = _shockwaveFlash->put_WMode(L"opaque");
Now it works as it should. Check you HRESULTs, kids :)