I am trying to force my application to stay on top of everything even when other processes pop up. Here's a simplified version of my main:
main.cpp
QApplication app{argc, argv};
QQmlApplicationEngine engine;
engine.load(QUrl{"qrc:/file.qml"});
return app.exec();
I need a solution for both Windows and Linux. However the priority is to the former and there doesn't seem to be a Qt solution. Here's what I tried:
#ifdef _WIN32
HWND hCurWnd = ::GetForegroundWindow();
DWORD dwMyID = ::GetCurrentThreadId();
DWORD dwCurID = ::GetWindowThreadProcessId(hCurWnd, NULL);
::AttachThreadInput(dwCurID, dwMyID, TRUE);
::SetWindowPos(hCurWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
::SetWindowPos(hCurWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
bool ok = ::SetForegroundWindow(hCurWnd);
LOG_INFO() << ok;
::AttachThreadInput(dwCurID, dwMyID, FALSE);
::SetFocus(hCurWnd);
::SetActiveWindow(hCurWnd);
#endif
ok returns true but it doesn't seem to work. External processes still appear on top of the application after its start.
The loaded QML file has its visibility set on FullScreen. Its type is ApplicationWindow.
Nevermind it was dumb simple:
setWindowFlags(Qt::WindowStaysOnTopHint) hides Qt Window
Therefore I wrote this in my file.qml:
ApplicationWindow
{
visibility: "FullScreen"
flags: Qt.WindowStaysOnTopHint
}
Related
I know this is similar to some other posts but still a little different...
I'm using the newest version of Xcode with SDL. The following code should show me a window but nothing happens except that I get the following message: Metal API Validation Enabled
Program ended with exit code: 0
When I disable this validation nothing happens at all. Any ideas on what might be wrong?
#include <SDL2/SDL.h>
#include <iostream>
int main() {
SDL_Init((SDL_INIT_VIDEO) <0);
SDL_Window *window;
window = SDL_CreateWindow("Title", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_SHOWN); //also tried different WINDOW_ input here
if (window == NULL) {
// In the case that the window could not be made...
printf("Could not create window: %s\n", SDL_GetError());
return 1;
}
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
SDL_Delay(3000);
}
````
I don't have enough reputation to comment, but for a start, the int main() should be replaced with int main(int argc, char* argv[]) and i'm not sure about SDL_Init((SDL_INIT_VIDEO) <0); just try SDL_Init(SDL_INIT_VIDEO); also, im not 100% about this I don't use mac, but if there are .dll on mac make sure you have the correct .dll files aswell (note what you're compiling (64bit or 32bit) use the corresponding .dll files)
I am new to VC++
I build a simple Win32 Application via default templet.
when i run it it shows a normal window with a menubar.
I added a system call that does a curl operation in InitInstance function:
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
//EDITED THIS WILL CREATE A FILE.HTML
system("curl www.google.co.in > file.html");
return TRUE;
}
all works fine.
But the problem is when ever i call system it opens in console window.
I want it to be a hidden process that does not shows that command prompt window..
help me with this.
The system function always shows a console window. If you want a hidden console window, you need to call CreateProcess directly. You can then ask for a DETACHED_PROCESS which runs without a console. Note that CreateProcess does not wait for the process to exit, so you will need to perform the wait yourself.
I put code in separate function, with url and filename as parameters.
#include <tchar.h>
#include <windows.h>
BOOL DownloadWithoutConsole(TCHAR* pszURI, TCHAR* pszFileName)
{
//here we will calculate our command line length in bytes
DWORD dwLen = (lstrlen(pszURI) + lstrlen(pszFileName) + 20)*sizeof(TCHAR);
//memory allocation for the command line
TCHAR* pszCmdLine = (TCHAR*)HeapAlloc(GetProcessHeap(), 0, dwLen);
ZeroMemory(pszCmdLine, dwLen);
//making command line
_stprintf_s(pszCmdLine,dwLen/sizeof(TCHAR), TEXT("cmd /c curl %s > %s"), pszURI, pszFileName);
//preparing arguments for CreateProcess
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));
//creating new process
BOOL bResult = CreateProcess(NULL, pszCmdLine, NULL, NULL, FALSE, CREATE_NO_WINDOW,
NULL, NULL, &si, &pi);
if(bResult)
{
//waiting for process termination
WaitForSingleObject(pi.hProcess, INFINITE);
//cleanup
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
//freeing memory
HeapFree(GetProcessHeap(), 0, pszCmdLine);
return(bResult);
}
int __cdecl _tmain(void)
{
DownloadWithoutConsole(TEXT("stackoverflow.com"), TEXT("test.txt"));
return(0);
}
Set nCmdShow to SW_HIDE(0) (ShowWindow). This way u will run it without he cmd prompt
I have this class here that I made based on another one I had. It is supposed to handle the whole creating windows and stuff, but it seems to be getting into a hang now. The older version used to work fine, I don't know WHAT I may have forgotten to add to this one that might be causing it to hang like this.
This is the message loop:
int Window::HandleMessages()
{
while(GetMessage(&this->windat.msgs, NULL, 0, 0))
{
TranslateMessage(&this->windat.msgs);
DispatchMessage(&this->windat.msgs);
}
return this->windat.msgs.wParam;
}
Pretty basic stuff, I don't know why, but it will simply hang... When I run the program, it'll just show me an empty prompt window, and by testing, I got it to show a message box if I used it before the while loop, but inside it doesn't work. I've been trying to compare both this class and the older one and haven't figured out what might be wrong with this. Could anyone tell me what could possibly trigger this behaviour?
Thanks
OK, now this left me pretty confused. By messing around with GetLastError, it seems that it is returning error 2 (file not found) ANYWHERE I put it, even if right at the start of the Main, before I instantiate my Window class. If I call GetLastError anytime after CreateWindowEx, it'll return an error like 1047 or something, about class not found or something. HWND becomes NULL too
Here is the code for the main.cpp:
#include "SimpWin/SimpWin.h"
#include <stdio.h>
// Make the class name into a global variable
char szClassName[] = "WindowsApp";
void ErrorExit(LPTSTR lpszFunction)
{
// Retrieve the system error message for the last-error code
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
// Display the error message and exit the process
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
sprintf((char*)lpDisplayBuf,
TEXT("%s failed with error %d: %s"),
lpszFunction, dw, lpMsgBuf);
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
ExitProcess(dw);
}
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil)
{
ErrorExit(TEXT("CreateWindowEx"));
Window* win = Window::CreateWindowClass(hThisInstance, szClassName, WindowProcedure);
if(!win->Register())
{
return 0;
}
win->Show(nFunsterStil);
int res = win->HandleMessages();
delete win;
return res;
}
/* This function is called by the Windows function DispatchMessage() */
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return DefWindowProc (hwnd, message, wParam, lParam);
}
This here, is the code for the Window::Register function:
int Window::Register()
{
if(this->windat.wincl.hIcon == NULL)
{
this->windat.wincl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
}
if(this->windat.wincl.hIconSm == NULL)
{
this->windat.wincl.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
}
if(!RegisterClassEx(&this->windat.wincl))
{
return 0;
}
this->windat.hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
(char*) this->windat.sName, /* Classname */
(char*) this->windat.sTitle, /* Title Text */
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
this->windat.cDimension.width, /* The programs width */
this->windat.cDimension.height, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
this->windat.hInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
return 1;
}
I'm lost here, I don't know why the eff this is going on... :/
Use PeekMessage instead of GetMessage.
Check the return value to GetMessage() - your while loop won't exit if there are errors. It should look like this:
while (GetMessage(&this->windat.msgs, NULL, 0, 0) > 0)
{
...
}
Well, I finally got it working! :D
It actually had to do with a completely unrelated class I had here. It is a String class (which descended from Array) which I made, and the copy function had a bug, it would copy the character array I passed to it, but would not update the length field of the class...
That copy function would be called whenever I had to set the class to a value through operator=. The length is required for the operator char* to convert the class to c-format string. I'd use that cast when passing the ClassName and Title values to CreateWindowEx, and it would return me an array of 0 chars, and that's where hell happened.
Now I fixed that lib up, and it's working fine now. Thanks :D
Even though it's pretty old... from MSDN on GetMessage:
Unlike GetMessage, the PeekMessage function does not wait for a message to be posted before returning.
That is, GetMessage waits for next message to become available. You treat this wait in progress as a freeze, supposedly because you did not actually have the intention to wait for messages.
Note that you can attach debugger at the time of supposed freeze, pause the execution and inspect the call stacks of the threads. Once you find your thread and its call stack and its GetMessage in progress on the stack - you isolate the problem well enough to know where to read on documented behavior.
Is there a win32 function to change the style of a window after it has been created? I would like to change the style flags that are specified in CreateWindowEx. Specifically, I would like to convert a standard window to a window with no border and no resize.
I think SetWindowLongPtr should do that. Note that you need to call SetWindowPos afterwards if you changed the border style, as pointed out in the remarks.
Some styles only take effect during window creation and so can not be set by this call. MSDN normally calls out styles that CAN be set afterwards.
HWND windowHandle = FindWindow(NULL, L"Various tests");
SetWindowLongPtr(windowHandle, GWL_STYLE, WS_SYSMENU); //3d argument=style
SetWindowPos(windowHandle, HWND_TOPMOST, 100, 100, Width, Height, SWP_SHOWWINDOW);
did it for me :D
You should try this window style in the createwindowex or SetWindowLongPtr: WS_POPUPWINDOW|WS_TABSTOP |WS_VISIBLE
The way i solved it by using combination of SetWindowPos and ShowWindow methods.
NOTE that calling showWindow is must here otherwise it won't work.
Here is the full source code below. Just call setConsoleWindowStyle() method and set new window style.
#define _WIN32_WINNT 0x0501
#include <stdio.h>
#include <windows.h>
LONG_PTR setConsoleWindowStyle(INT,LONG_PTR);
int main()
{
LONG_PTR new_style = WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL;
setConsoleWindowStyle(GWL_STYLE,new_style);
return 0;
}
LONG_PTR setConsoleWindowStyle(INT n_index,LONG_PTR new_style)
{
/*The function does not clear the last error information. if last value was zero.*/
SetLastError(NO_ERROR);
HWND hwnd_console = GetConsoleWindow();
LONG_PTR style_ptr = SetWindowLongPtr(hwnd_console,n_index,new_style);
SetWindowPos(hwnd_console,0,0,0,0,0,SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_DRAWFRAME);
//show window after updating
ShowWindow(hwnd_console,SW_SHOW);
return style_ptr;
}
SetWindowLong(hWnd, GWL_STYLE, newStyle);
ShowWindow(hWnd, SW_SHOW);
I'm working on a portability layer for OpenGL (abstracts the glX and wgl stuff for Linux and Windows)... Anyhow, it has a method for creating a Window... If you don't pass in a parent, you get a real window with a frame... If you pass in a parent, you get a borderless, frameless window...
This works fine, as long as I do it all on 1 thread... As soon as another thread tries to create a child window, the app deadlocks in the win32 call "CreateWindow()". Any ideas?
This is not a real answer, but since so many people seem to believe that Win32 forbids creating children in other threads than the parent, I feel obliged to post a demonstration to the contrary.
The code below demonstrates creation of a child window on a parent belonging to a different process. It accepts a window handle value as a command-line parameter and creates a child window on that parent.
// t.cpp
#include <windows.h>
#include <stdio.h>
#define CLASS_NAME L"fykshfksdafhafgsakr452"
static LRESULT CALLBACK WindowProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch ( msg )
{
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(hwnd, &ps);
EndPaint(hwnd, &ps);
break;
}
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
int main( int argc, char* argv[] )
{
HWND parent = (argc >= 2) ? (HWND)strtoul(argv[1], 0, 0) : (HWND)0;
printf("parent: 0x%x\n", parent);
WNDCLASS wc = {};
wc.lpfnWndProc = WindowProc;
wc.hInstance = (HINSTANCE)GetModuleHandle(NULL);
wc.lpszClassName = CLASS_NAME;
wc.hbrBackground = (HBRUSH)(COLOR_ACTIVECAPTION + 1);
if ( !RegisterClass(&wc) )
{
printf("%d: error %d\n", __LINE__, GetLastError());
return 0;
}
const DWORD style = WS_CHILD | WS_VISIBLE;
HWND hwnd = CreateWindow(CLASS_NAME, L"Test", style, 50, 50, 100, 100,
parent, 0, wc.hInstance, 0);
if ( !hwnd )
{
printf("%d: error %d\n", __LINE__, GetLastError());
return 0;
}
MSG msg;
while ( GetMessage(&msg, 0, 0, 0) )
DispatchMessage(&msg);
return 0;
}
Compile this with the following command (using MSVC command line environment):
cl /EHsc /DUNICODE /D_UNICODE t.cpp user32.lib
Then use Spy++ or some other tool to obtain handle value of any window -- e.g. of Notepad or the browser you're viewing this site in. Let's assume it's 0x00001234. Then run the compiled sample with t.exe 0x1234. Use Ctrl-C to terminate t.exe (or just close the console window).
When a child window is created, it can interact with the parent window via SendMessage. But, note that SendMessage across thread boundary blocks threads unlike PostMessage. If the parent window's thread is waiting for the child thread, and the child thread is trying to create a window whose parent is in that thread, then it's a deadlock.
In general, I don't think it's a good idea to make child-parent relationship across the threads. It can very easily make deadlock.
There are a lot of replies here saying that you MUST NOT attempt to have child and parent windows on different threads, and rather emphatically stating that it will not work.
If that was so, Windows would put some safeguards in and simply fail out when you attempted to call CreateWindow.
Now, there definitely are thread coupling issues that can cause major issues, but, that said with those constraints, this is a supported scenario.
This is an interesting question: A lot of old school win32 guys have told me you CANNOT do this. In researching this, I found this forum: SendMessage(). My current theory is that CreateWindowEx() must send a message (via SendMessage(), so it blocks) to the parent window to ask for permission to exist (or at least to notify of its existence)... Anyhow, as long as that parent thread is free to process these messages, it all works...
A window is tied to the thread that creates it (more specifically, to that thread's message queue). A parent window cannot reside in a different thread than its child windows.