Related
I have two windows, one smaller on top of other bigger. The window created first will always be on top. Neither BringWindowToTop(hWnd) nor SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); do nothing! I also have been trying HWND_TOPMOST and HWND_BOTTOM.
It seems the only way to make one window on top of other is a correct creation order. But this is not what I need, I need to change the order on the fly. Anyone knows what could cause this? Those are just old plain CreateWindow() instances both have the same parent. Any search on internet yields nothing. Need some expert help!
#include <windows.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
HWND make_child(HWND Parent, int x, int y, int color) {
HINSTANCE hInstance = 0;
MSG msg = {0};
WNDCLASS wc = {0};
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hbrBackground = CreateSolidBrush(color);//(HBRUSH)(COLOR_WINDOWFRAME);
wc.lpszClassName = (LPCSTR)L"mychildwin";
RegisterClass(&wc);
return CreateWindow("edit",(LPCSTR)"child", WS_BORDER|WS_CHILD|WS_VISIBLE, x,y,100,100,Parent,0,hInstance,NULL);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
MSG msg = {0};
WNDCLASS wc = {0};
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hbrBackground = CreateSolidBrush(0xff8080);
wc.lpszClassName = (LPCSTR)L"minwindowsapp";
if (!RegisterClass(&wc)) return 1;
HWND W = CreateWindow(wc.lpszClassName,(LPCSTR)L"Minimal Windows Application", WS_OVERLAPPEDWINDOW|WS_VISIBLE, 0,0,640,480,0,0,hInstance,NULL);
HWND A = make_child(W, 10, 10, 0x88ff00);
HWND B = make_child(W, 70, 70, 0x8888ff);
BringWindowToTop(B);
SetWindowPos(B, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
//REAL PROBLEM WAS HERE: A second call to SetWindowPos
SetWindowPos(handle, 0, 0, 0, new_width, new_height,
SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOACTIVATE);
// adding SWP_NOZORDER fixed it..
while(GetMessage(&msg, NULL, 0, 0) > 0) DispatchMessage(&msg);
return 0;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch(message) {
case WM_CLOSE: PostQuitMessage(0); break;
default: return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
According to the MSDN-documentation, there is also the possibility to pass a window-handle to the window you want your window to be inserted after.
BOOL WINAPI SetWindowPos(
_In_ HWND hWnd,
_In_opt_ HWND hWndInsertAfter,
_In_ int X,
_In_ int Y,
_In_ int cx,
_In_ int cy,
_In_ UINT uFlags
);
where hWndInsertAfter is the handle of the window your window shall be positioned AFTER. Have you tried this one?
Ok, maybe someone will find it really useful. Because real problem was that SetWindowPos and BringWindowToTo both worked fine, but afterwards in my real app I was calling SetWindowPos again to move the component a little, and it was screwing the ZOrder again!
So I added SWP_NOZORDER to that second call to SetWindowPos.
I am developing an Win32 application where user logins when the application starts in a login window and then the main window opens
But when I run the program nothing appears.
Here's the code
HINSTANCE ghInstance;
HWND hWnd;
HWND hWndPopUp;
LRESULT WINAPI PopUpWndProc( HWND hWnd2, UINT msg, WPARAM wParam, LPARAM lParam );
LRESULT WINAPI MainWndProc( HWND hWnd , UINT msg , WPARAM wParam , LPARAM lParam );
int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance , LPSTR lpszCmdLine , int nCmdShow){
WNDCLASS wc;
WNDCLASS wcPopUp;
MSG msg;
//HWND hWnd;
BOOL bRet;
if( !hPrevInstance )
{
wc.lpszClassName = L"MainAppClass" ;
wc.lpfnWndProc = MainWndProc ;
wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW ;
wc.hInstance = hInstance ;
wc.hIcon = LoadIcon( NULL, IDI_APPLICATION ) ;
wc.hCursor = LoadCursor( NULL, IDC_ARROW ) ;
wc.hbrBackground = (HBRUSH)( COLOR_WINDOW+1 ) ;
wc.lpszMenuName = NULL ;
wc.cbClsExtra = 0 ;
wc.cbWndExtra = 0 ;
RegisterClass( &wc ) ;
wcPopUp.lpszClassName = L"PopUpAppClass" ;
wcPopUp.lpfnWndProc = PopUpWndProc ;
wcPopUp.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW ;
wcPopUp.hInstance = hInstance ;
wcPopUp.hIcon = LoadIcon( NULL, IDI_APPLICATION ) ;
wcPopUp.hCursor = LoadCursor( NULL, IDC_ARROW ) ;
wcPopUp.hbrBackground = (HBRUSH)( COLOR_WINDOW+1 ) ;
wcPopUp.lpszMenuName = NULL ;
wcPopUp.cbClsExtra = 0 ;
wcPopUp.cbWndExtra = 0 ;
RegisterClass( &wcPopUp );
}
ghInstance = hInstance;
hWndPopUp = CreateWindowEx(WS_EX_CONTEXTHELP,
wcPopUp.lpszClassName,
L"Stock Ticker Login",
WS_OVERLAPPEDWINDOW,
0,
0,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL
);
bool show = ShowWindow( hWndPopUp, SW_MAXIMIZE ) ;
UpdateWindow(hWndPopUp);
hPE = NULL;
/** While there is no WM_QUIT message in the Message Queue
Fetch Message from the queue and Dispatch it to WindowProc()
**/
while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0 )
{
if (bRet == -1)
{
// handle the error and possibly exit
int nerror = GetLastError();
MessageBox(hWnd,L"Window Error",L"Window error", MB_ICONERROR);
exit(1);
}
else {
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
return (int)msg.wParam;
}
LRESULT WINAPI PopUpWndProc( HWND hWnd2, UINT msg, WPARAM wParam, LPARAM lParam ){
HDC hdc;
PAINTSTRUCT ps;
RECT rc;
GetClientRect(hWnd, &rc);
int height = rc.bottom - rc.top;
int width = rc.right -rc.left;
switch( msg )
{
case WM_CREATE:
hWndStaticUsername = CreateWindowEx( 0
, L"static"
, L"Username"
, WS_CHILD | WS_VISIBLE
, rc.left + width/8
, rc.top + height/4
, 100
, 30
, hWnd2
, 0
, ghInstance
, 0
);
hWndEditUsername = CreateWindowEx( WS_EX_CLIENTEDGE
, L"edit"
, L""
, WS_CHILD | WS_VISIBLE
, rc.left + width/8 + 150
, rc.top + height/4
, 150
, 30
, hWnd2
, 0
, ghInstance
, 0
);
hWndBtnLogin = CreateWindowEx( 0
, L"button"
, L"Login"
, WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON
, rc.left + width/8
, rc.top + height/4 + 80
, 50
, 30
, hWnd2
, 0
, ghInstance
, 0
);
break;
case WM_COMMAND:
if(HIWORD(wParam)== BN_CLICKED && lParam==(LPARAM)hWndBtnLogin )
{
TCHAR* uname =new TCHAR;
Edit_GetText(hWndEditUsername, uname, 20);
if(wcscmp(uname,L"")==0)
return 0;
else
{
StartTicker(uname);
DestroyWindow(hWnd);
}
}
break;
case WM_DESTROY:
hWnd = CreateWindowEx(WS_EX_CONTEXTHELP,
L"MainAppClass",
L"Assignment 2",
WS_OVERLAPPEDWINDOW,
0,
0,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
ghInstance,
NULL
);
ShowWindow( hWnd, SW_MAXIMIZE ) ;
UpdateWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, msg, wParam, lParam );
}
return 0;
}
Please help me find the solution.
return DefWindowProc(hWnd, msg, wParam, lParam );
Wrong window handle, it should be hWnd2.
To uplift this post beyond a 'debug my code for me' answer, there are two fundamental things you do wrong, they are going to get you into a lot more trouble:
too sloppy on picking good variable names. You should never have a global variable named "hWnd". That should of course be hWndMain, you'd have never made that mistake.
no error check whatsoever. If you had any, you would have quickly discovered that CreateWindowEx() returned NULL and GetLastError() returned 1400. Without error checking, you can only watch it misbehave but never diagnose it.
Using the raw winapi requires meticulous attention to such small details. Consider using a class library instead.
how come you are calling:
ShowWindow( hWnd, SW_MAXIMIZE ) ;
UpdateWindow(hWnd);
only after and in the scope of: case WM_DESTROY:
I would imagine you call ShowWindow in normal execution and not in the distruction :)
BTW the remaining buffer will automatically increase if the other side reads data out of it,right?
How about PeekNamedPipe? It would seem that the following will return the total number of bytes remaining to be read from the pipe.
DWORD totalBytesAvailable;
BOOL WINAPI PeekNamedPipe(
handle, // __in HANDLE hNamedPipe,
NULL, // __out_opt LPVOID lpBuffer,
0, // __in DWORD nBufferSize,
NULL, // __out_opt LPDWORD lpBytesRead,
&totalBytesAvailable, // __out_opt LPDWORD lpTotalBytesAvail,
NULL // __out_opt LPDWORD lpBytesLeftThisMessage
);
I want to make a screen shot and display it in the window of my program, but so far I have only been able to make the screen white.
What am I doing wrong?
Code:
#include <windows.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("screen") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("Program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow (szAppName, TEXT ("Digital Clock"),
WS_POPUP|WS_DLGFRAME|WS_VISIBLE, //WS_OVERLAPPEDWINDOW| WS_MAXIMIZE,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd, SW_MAXIMIZE);// iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static BOOL f24Hour, fSuppress ;
static HBRUSH hBrushRed ;
static int cxClient, cyClient ;
HDC hdc ;
PAINTSTRUCT ps ;
TCHAR szBuffer [2] ;
HGDIOBJ hMem; // HBITMAP hMem;
HDC compdc;
switch (message)
{
case WM_CREATE:
hBrushRed = CreateSolidBrush (RGB (255, 0, 0)) ;
keybd_event(VK_SNAPSHOT, 0, KEYEVENTF_EXTENDEDKEY, 0); //get screen snapshot into clipboard
OpenClipboard(NULL);
hMem = GetClipboardData(CF_BITMAP);
case WM_SETTINGCHANGE:
return 0 ;
case WM_SIZE:
cxClient = LOWORD (lParam) ;
cyClient = HIWORD (lParam) ;
return 0 ;
case WM_TIMER:
InvalidateRect (hwnd, NULL, TRUE) ;
return 0 ;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
compdc = CreateCompatibleDC(hdc);
SelectObject(compdc,hMem);
BitBlt(hdc,0,0,cxClient,cyClient,compdc,20,20,SRCCOPY);
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_KEYDOWN:
switch(wParam)
{
case VK_ESCAPE:
DeleteObject (hBrushRed);
PostQuitMessage (0) ;
}
case WM_DESTROY:
DeleteObject (hBrushRed) ;
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
First of all, I'd avoid using the clipboard like this does -- the user should see changes in the clipboard only after an explicit cut or copy.
Instead, you should capture the contents of the screen directly. Given that you're doing this with raw Win32 calls, you'd start by defining a couple of extra variables in your WndProc:
static HBITMAP bmp;
static RECT r;
Then in your WM_CREATE handler, you'd have code something like this to actually capture the screen:
{
// First get a DC to the entire screen.
HDC s = GetDC(NULL);
// Then get the size of the screen:
r.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
r.right = GetSystemMetrics(SM_CXVIRTUALSCREEN);
r.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
r.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN);
// Then create a bitmap to hold the picture of the screen:
bmp = CreateCompatibleBitmap(s, r.right, r.bottom);
// Create a memory DC and select that BMP into it:
HDC mem=CreateCompatibleDC(s);
HBITMAP old = (HBITMAP)SelectObject(mem, bmp);
// Copy the bits from the screen to our DC (and our BMP that's selected into it.
BitBlt(mem, 0, 0, r.right, r.bottom, s, 0, 0, SRCCOPY);
// Clean up:
SelectObject(mem, old);
DeleteDC(mem);
ReleaseDC(NULL, s);
}
break;
Then in your WM_PAINT handler, you'd have code like this to draw that to your window:
{
hdc = BeginPaint(hWnd, &ps);
// Create a compatible DC and select our BMP into it:
HDC mem=CreateCompatibleDC(hdc);
HBITMAP old = (HBITMAP)SelectObject(mem, bmp);
// Copy bits from our BMP to our window:
BitBlt(hdc, 0, 0, r.right, r.bottom, mem, 0, 0, SRCCOPY);
// Clean up:
SelectObject(hdc, old);
DeleteDC(mem);
EndPaint(hWnd, &ps);
break;
}
How can I make a true full screen mode in VC++?
Code:
#include <windows.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("screen") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("Program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow (szAppName, TEXT ("Digital Clock"),
WS_POPUP|WS_DLGFRAME|WS_VISIBLE, // _OVERLAPPEDWINDOW| WS_MAXIMIZE,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd, SW_MAXIMIZE);// iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
Does
SetWindowPos( hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
not put it on top of the taskbar?
Check out this function and look at the definition of WS_EX_TOPMOST...
See Can a window be always on top of just one other window?
In case of multiple window set to AlwaysOnTop; than only that window will remain on top that has been manually brought on top. For instance there are two windows Window1 and Window2; then when you would run window1.exe, it would be the window on top; and when you would run window2.exe then that window would be on top, thats the default behavior.
Otherwise if you must not allow any other window to get on top, you will have to look for other apps being invoked after yours, and then probably hook those windows somehow and, well probably call its Minimize event to send it to the task bar.
Games usually use DirectX which has a mode that takes exclusive use of the video output - this means no other window (or task bar) can draw to the screen and the whole screen is available to the application at whatever resolution and colour depth you want (well almost, whatever the video card supports).