How can I animate two windows at the same time? I tried:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern bool AnimateWindow(IntPtr hwnd, int time, int flags);
...
AnimateWindow(panel1.Handle, speed, AW_SLIDE | AW_HOR_Top);
AnimateWindow(panel2.Handle, speed, AW_SLIDE | AW_HOR_Top);
But panel2 will not animate until panel1 finished its animation.
I must use the threading .. but i can't even if i used invoke .. also it runs the 2nd animation after the 1st
so how can i do it ?
If both windows were created by the same thread, then the AnimateWindow function will run on that thread. According to the MSDN documentation:
The function will fail in the following situations:
If the thread does not own the window. Note that, in this case, AnimateWindow fails but GetLastError returns ERROR_SUCCESS.
There is no way around this other than creating the second window on a separate thread. Additionally, you will have to call the AnimateWindow function from the thread that each window was created on.
Related
Within a modeless DialogBoxProcedure(), I implemented two main functions:
Constant movement along the X and Y axis using SetWindowPos(), each movement activated by a timer. (Essentially making the Dialog Box bounce around the screen). I did this by using static int to set the variables, and adjust them accordingly upon receiving a new timer message.
Recursively Creating a new DialogBox by calling CreateDialog() whenever the original Dialog Box receives the appropriate message to do so.
I wanted the new recursively created dialog box to call on its own DialogBoxProcedure with its own set of static variables so it could move independently, but what ended up happening was the new DialogBox was stacked exactly on top of the previous dialog box,probably because of the usage of static variables in the DialogProcedure. Is there a way to fix this?
You can't create multiple instances of the same dialog procedure. You can use the same dialog procedure more than once and make sure it knows which dialog it's talking about.
Store the variables in some kind of structure and make two instances of that, for example using malloc or just two different global or static variables.
Then:
Instead of CreateDialog use CreateDialogParam and give it a pointer:
// instead of
hWndDialog = CreateDialog( hInstance, IDD_MY_DIALOG, hWndParent, MyDialogProc);
// use:
hWndDialog = CreateDialogParam(hInstance, IDD_MY_DIALOG, hWndParent, MyDialogProc, pMyDialogStruct1);
// ^^^^^ ^^^^^^^^^^^^^^^^
When your dialog proc gets a WM_INITDIALOG message, that pointer is in lParam. You can then transfer it to the HWND by using SetWindowLongPtr(DWLP_USER):
SetWindowLongPtr(hWnd, DWLP_USER, (LONG_PTR)lParam);
Now the struct pointer is stored in the HWND and you can get it back at any time:
MyDialogStruct* dlgStruct = (MyDialogStruct*)GetWindowLongPtr(hWnd, DWLP_USER);
I'm using the SetWindowPos function for an automation task to show a window. I know that there are two ways that Windows provides to do this:
Synchronously: SetWindowPos or ShowWindow.
Asynchronously: SetWindowPos with SWP_ASYNCWINDOWPOS or ShowWindowAsync.
Now, I'd like to get the best of both worlds: I want to be able to show the window synchronously, because I'd like it to be done when the function returns. But I don't want the call to hang my process - if it takes too long, I want to be able to abort the call.
Now, while looking for an answer, the only thing I could come up with is using a separate thread and using SendMessageTimeout, but even then, if the thread hangs, there's not much I can do to end it except of TerminateProcess, which is not a clean solution.
I also have seen this answer, but as far as I understand, it has no alternative for native WinAPI.
The answer in the question you linked to simply loops until either the desired condition occurs or the timeout expires. It uses Sleep() every iteration to avoid hogging the processor. So a version for WinAPI can be written quite simply, as follows:
bool ShowWindowAndWait(HWND hWnd, DWORD dwTimeout) {
if (IsWindowVisible(hWnd)) return true;
if (!ShowWindowAsync(hWnd, SW_SHOW)) return false;
DWORD dwTick = GetTickCount();
do {
if (IsWindowVisible(hWnd)) return true;
Sleep(15);
} while (dwTimeout != 0 && GetTickCount() - dwTick < dwTimeout);
return false;
}
Unfortunately I think this is the best you're going to get. SendMessageTimeout can't actually be used for this purpose because (as far as I know anyway) there's no actual message you could send with it that would cause the target window to be shown. ShowWindowAsync and SWP_ASYNCWINDOWPOS both work by scheduling internal window events, and this API isn't publicly exposed.
I am trying to automate an external Windows application. The goal is to make this application start minimized without showing any active window/splash screens and without stealing focus from other applications.
I wrote a little program on C that calls EnumWindows() in a loop and uses ShowWindow() to minimize the required window. It is quite fast and works in 80% of cases. Unfortunately, sometimes the application window is still showing and stealing the focus for a short period of time.
What would be a better (sure) way to intercept the window?
Is using SetWindowsHookEx hooks the only alternative?
Have you tried using the wShowWindow member of the STARTUPINFO structure you pass to CreateProcess() when starting the application? That was designed to do exactly things like this.
If dwFlags specifies STARTF_USESHOWWINDOW, this member can be any of the values that can be specified in the nCmdShow parameter for the ShowWindow function, except for SW_SHOWDEFAULT. Otherwise, this member is ignored.
For GUI processes, the first time ShowWindow is called, its nCmdShow parameter is ignored wShowWindow specifies the default value. In subsequent calls to ShowWindow, the wShowWindow member is used if the nCmdShow parameter of ShowWindow is set to SW_SHOWDEFAULT.
For example:
STARTUPINFO si = { sizeof(si) }
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_MINIMIZE;
CreateProcess(..., &si, ...);
I'll try to be explicit. I create a Qt application, that has some buttons and a QTextEdit. Next i create a pthread. And offer the pointer to the MainWindow as the parameter. Something like this:
MainWindow w;
pthread_create(&rThread,NULL,treat,&w);
treat is the function that is executed when the thread is created. Now if i have a pushButton called myButton, and i do somthing like this inside the treat function:
void *treat(void *arg)
{
MainWindow *win = (MainWindow*)arg;
win->ui->myButton->setEnabled(false);
close(pthread_self());
}
It will work fine , and the myButton in my application will disable. However if i do something like this:
void *treat(void *arg)
{
MainWindow *win = (MainWindow*arg;
win->ui->editText->setText("random string");
close(pthread_self());
}
My application will crash with the following error:
QObject: Cannot create children for a parent that is in a different
thread. (Parent is QTextDocument(0x23af2e0), parent's thread is
QThread(0x209a290), current thread is QThread(0x7f7eec000af0) The
program has unexpectedly finished.
As i understand the Ui is living in the main thread, and probably is not accesible in the thread that i created , despite the fact that i offered the pointer of the main window to this thread. But why does disabling of the button work? I am very confused. The reason why i dint use the QThread is because our teacher told me not do it. I have to use pthreads. How could i apply such a change from the pthread to the editText ?
How could i send a signal from a pthread to the other thread in wich the Ui is "living". Thanks in advance guys.
Generally speaking, it's an error to call any of QObject (or derived classes') methods from a thread other than object->thread() - unless they are designed and documented to be thread-safe. There are a few methods in Qt proper that are explicitly documented as being thread safe, for example QCoreApplication::postEvent.
The behavior you're facing is due to accessing QWidget methods from the non-gui thread. It's undefined behavior, so some methods may crash, some won't, but even if they don't it's still undefined behavior that you can't count on. It may depend on the phase of the Moon, for all we know.
The only safe thing to do from another thread is to post an event to the object. When you use QMetaMethod::invoke or QMetaObject::invokeMethod on an object in another thread, Qt will internally post a QMetaCallEvent to the object. Since posting events is thread-safe (can be done from other threads), it's OK to do use either of those invoke methods from other threads. QObject::event() reacts to such events by executing the proper method call.
So, the only thing you can do from the other thread is:
QMetaObject::invokeMethod(win->ui->editText, "setText", Q_ARG(QString, "random string"));
Alas, this is bad design, since you're exposing MainWindow's internal details (like the ui pointer) to outside. What you should do instead is have a setEditText slot on the window:
MainWindow : public QWidget {
...
public:
Q_SLOT void setEditText(const QString & str) {
ui->editText->setText(str);
}
...
};
Then, from the other thread, you do:
QMetaObject::invokeMethod(win, "setEditText", Q_ARG(QString, "random string"));
I fully agree with Marek R's recommendation not to use pthreads when you have QThread available.
First of all mixing libraries when it is not necessary is bad habit. Qt provides QThread and very handy QtConcurrent.
Secondly this is bad design. Create some QObject which will handle yours calculations in thread and will emit signal when it should pass result to UI (main thread). Then create connection and Qt will handle rest of the stuff make it thread safe (by default it will queue connection if signal is passed between threads).
Your code with Qt concurrent:
void *treat(SomeClass *arg) {
arg->doStuff();
}
QtConcurrent::run(treat, someObject);
since I couldn't find an answer to this question I researched a bit further into the MSDN and I found isChild(). It might give me the answer to that other question.
Now, in order to use isChild() I need to pass the HWND of the parent application that I want to check, in this case my own application.
How do I get the HWND of my own application?
I don't know the title since it changes constantly so I can't use FindWindow().
Thanks
Edit:
Since it's not clear, I'll add more information:
I am not creating a window. I don't have access to the creation of a window. My code is a piece of code that gets compiled together with whatever application the other programmer is coding and I have no access to how the window is created, the title or any other information.
So, how do I get the HWND to the "WINDOW" of the application I am running?
Your application doesn't have a HWND. The window does. An application may have no windows or it may have many, so there is no general function to "Get the application's HWND".
The obvious solution is just to hold on to the handle when you get it. When you create the window, a HWND is returned. Store that.
Use GetTopWindow() and GetNextWindow() to walk through windows z-order.
However, don't think it is necessary, but you can use GetCurrentProcessId() and
GetWindowThreadProcessId(), may be something like following will help you:
HWND FindMyTopMostWindow()
{
DWORD dwProcID = GetCurrentProcessId();
HWND hWnd = GetTopWindow(GetDesktopWindow());
while(hWnd)
{
DWORD dwWndProcID = 0;
GetWindowThreadProcessId(hWnd, &dwWndProcID);
if(dwWndProcID == dwProcID)
return hWnd;
hWnd = GetNextWindow(hWnd, GW_HWNDNEXT);
}
return NULL;
}
Can't you just hold onto the handle returned from CreateWindow? If not, why not?
Presumably your code gets called by main application code, otherwise what use is it? In which case I acnnot see why your code's API cannot include some way of informing you of the handle of the application's main window.
As others have already pointed out
In general, an application can have zero or multiple top-level windows.
If you're creating the window yourself you can just remember the HWND somewhere.
But maybe your code is in a DLL, so you didn't actually create the top-level window yourself. So what to do?
I would suggest the following:
Use EnumWindows to enumerate all top-level windows.
Use GetWindowLongPtr to get the HINSTANCE for each top-level window. Compare this against the HINSTANCE of the application, which you can get using GetModuleHandle(NULL). If they're identical, you've found your main window.
Edit: Here is some code. Turns out you also have to use IsWindowVisible because there seem to be quite a few invisible "helper" windows.
HWND hwndMain;
BOOL CALLBACK EnumWindowProc(HWND hwnd, LPARAM lParam)
{
HINSTANCE hinst=(HINSTANCE)GetModuleHandle(NULL);
if((HINSTANCE)GetWindowLongPtr(hwnd, GWL_HINSTANCE)==hinst &&
IsWindowVisible(hwnd))
{
hwndMain=hwnd;
return FALSE;
}
else
return TRUE;
}
Then in the place you want to find the window:
hwndMain=NULL;
EnumWindows(EnumWindowProc, 0);
And after this, hwndMain should contain the handle of the window, or NULL if none exists.
Using EnumWindows is a bit burdensome but is recommended over calling GetWindow in a loop because, as MSDN notes: "An application that calls GetWindow to perform this task risks being caught in an infinite loop or referencing a handle to a window that has been destroyed."
You can inject a DLL in a thread who appeal user32.dll
http://msdn.microsoft.com/en-us/library/ms821625.aspx
This is old for me, but IIRC you should receive the HWND as a parameter in the window proc. You can save it in a global variable somewhere in the beginning.
What about your windows class name?
Is it always different on window creation?
If not you could still you FindWindow().