|
Excuse me again...
But if i've 3 threads and these 3 threads creates windows with their own message loop; how can i implement it in the loops of these windows, because if i'm not mistaken these threads never ends and so their never will be signaled, then i must create a timer or another thing but which is the best option to use?
|
|
|
|
|
One of the handles the MsgWaitForMultipleObjects waits upon can be an event that the main thread of your progrma will set. When each event is signaled, then each thread can post a WM_CLOSE to its window. When the window closes, the thread detects that (maybe the window sets a thread-specific variable) and then the thread exits. When all threads have exited, then the main progrma thread will exit. The main program thread can be waiting for the thread handles to be signaled, indicating the working threads have all exited. That is why they have MsgWaitForMultipleObjects, so you can have several different signals a thread is waiting for. You need to have the worker thread waiting for its 'do the work' signal (if there is one, otherwise it is just servicing the window) and at least wait on an event that the main thread sets to let the working thread know to exit.
When the working thread is processing the messages, using GetMessage, TranslateMessage, and DispatchMessage, the message will reach the correct window, so you don't have to worry about that.
Another way to get a thread to exit is to use PostThreadMessage, if you know the thread is processing messages, and you can post a specifc message that the thread can intercept to know it is time to exit. You can tell it is a thread-targeted message when you call GetMessage, because the 'hwnd' member of the MSG data structure will be NULL.
|
|
|
|
|
How do I do this? I have an application that uses GetCursorPos() to get the current mouse position, but I want to send it my own coordinates.
|
|
|
|
|
Is this what you are looking for?
SetCursorPos(int x, int y);
humpa humpa
|
|
|
|
|
No, I don't want to just do SetCursorPos (unless I did it inside of GetCursorPos, but that would be pointless) because the application calls it very often, and that results in the mouse shaking.
EDIT: Don't worry about the shaking, all I want to know is how to hook GetCursorPos()
|
|
|
|
|
Nevermind, I figured it out on my own.. I just had to hook GetProcAddress and check if the proc was "GetCursorPos", then save the pointer to the origonal and return mine.
|
|
|
|
|
As the subject said, I´m having troubles with my dialogbox. I cant move it .
This is what I´ve written:
IDD_DIALOG1 DIALOGEX 0, 0, 196, 102
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION
CAPTION "Dialog"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,139,7,50,14
PUSHBUTTON "Cancel",IDCANCEL,139,24,50,14
END
----------------------------------
WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR CmdLine, int CmdShow)
{
...
DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG1), hWnd, (DLGPROC)DlgProc);
...
}
----------------------------------
bool CALLBACK DlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_INITDIALOG:
return true;
case WM_MOVE:
break;
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case IDOK:
EndDialog(hWnd,0);
return TRUE;
case IDCANCEL:
break;
}
break;
}
default:
return false;
}
return true;
}
I can use the buttons and shutdown the dialogbox. As I said, I just cant move it.
I´m using VS.NET 2003, any suggestions would be helpful.
Thanks.
|
|
|
|
|
If you don't handle a message, you should be calling [edit]DefWindowProc()[/edit] to allow Windows to perform default processing for the message. In your case, the problem is probably because Windows doesn't get a chance to handle WM_NCLBUTTONDOWN or WM_NCHITTEST , so it doesn't have a chance to allow the user to move the window.
[edit]Sorry, don't use DefDlgProc() from inside your dialog box procedure. Infinite recursion followed by a program crash will probably result. Use DefWindowProc() instead[/edit]
Ryan "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
|
|
|
|
|
Look at what your dialog proc is doing when it receives WM_MOVE . It does nothing, then returns true , which means that you handled the message. Since you did nothing, nothing happens. Return FALSE instead to let the system do the default behavior for that message.
BTW, the dialog proc return value is a BOOL , not bool . This is important for messages that return more than just a flag such as WM_CTLCOLOR*
--Mike--
Personal stuff:: Ericahist | Homepage
Shareware stuff:: 1ClickPicGrabber | RightClick-Encrypt
CP stuff:: CP SearchBar v2.0.2 | C++ Forum FAQ
----
I even hear the Windows "OMG I booted up fine" sound.
-- Paul Watson diagnosing hardware problems.
|
|
|
|
|
Hi Everybody,
I developed an application Using Embedded VisualVC++ 4.0 and Windows CE.
In my application, I would like to add Rounded Shape or any irregular shape dialogs.
In Windows2000 most of the functions support the same.
Can anyone know to make a dialog as rounded shape in Windows CE?
Please answer my question.
Thanks inadvance,
pandi.
|
|
|
|
|
Just create a non rectangular region and assign it to the CDialog window...
Since CreateEllipticRgn is not supported on Windows CE you`ll have to create rounded shaped regions yourself by combining rectangular regions.
I did it in a Win32 application I designed in Windows CE4.0 for an ARM device and a MIPS device and it worked beautifully! Offcourse it isn^t MFC but I guess the procedure is the same!
Greetz,
Davy
|
|
|
|
|
Hi Davy,
Thanks for your reply.
How can i create rounded shaped regions by combining rectangular regions?
Please answer to my question.
Thanks inadvance,
Pandi.
|
|
|
|
|
void DW::OnSubmit()
{
typedef char INFO[225];
INFO ALL[6];
CFile UTP;
CString k;
CEdit *GTINFO[6];
GTINFO[0]=(CEdit*) GetDlgItem(IDC_EDIT1);
UTP.Open("C:\\az.qiz",CFile::modeReadWrite|CFile::modeNoTruncate);
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//++++++++++++++++++GET TEXT+++++++++++++++++++++++++++++++++++++++++
GTINFO[0]->GetWindowText(ALL[0],(GTINFO[0]->GetWindowTextLength()+1));
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//++++++++++++++++++++++++++++WRITE TO FILE+++++++++++++++++++++
k.Insert(k.GetLength()+1,ALL[0]);
k.Insert(0,"\r\n");
UTP.Write(k,k.GetLength());
MessageBox(k,"test",MB_OK); //this worked
///}
}
|
|
|
|
|
Man, your commenting style is damn ugly.
None of this code does any checking, it all just assumes that it works. In the absence of any comments as to what happens when it fails, it's kind of hard to help.
Christian
I have several lifelong friends that are New Yorkers but I have always gravitated toward the weirdo's. - Richard Stringer
|
|
|
|
|
You've not provided any useful information. For example:
What doesn't work?
Does it compile/link okay?
Are any assertions fired?
Are any exceptions thrown?
Have you stepped through the code to see which line is in error?
What value(s) do the variables have as you step through the code?
"When I was born I was so surprised that I didn't talk for a year and a half." - Gracie Allen
|
|
|
|
|
GTINFO[0]->GetWindowText(ALL[0],(GTINFO[0]->GetWindowTextLength()+1));
That's one weird line of code ....
what exacly you want to do ? get the text from all CEdit and write them to to a file ?
Maximilien Lincourt
Your Head A Splode - Strong Bad
|
|
|
|
|
get the string from an edit box and write it to a line in a text file
|
|
|
|
|
why don't you simply call CWnd::GetWindowText( CString& ) ?
seems you are complexifying things a wee bit ...
Maximilien Lincourt
Your Head A Splode - Strong Bad
|
|
|
|
|
You mast write, won won't work in you code (if you debug it )
For fist look, the general error in that lines :
ANDYFA wrote:
k.Insert(k.GetLength()+1,ALL[0]);
k.Insert(0,"\r\n");
wht you want to do : insert string on 1-st position in zero length string , and then prepend it whith CRFL
Try this:
k += CString(ALL[0])+CString("\r\n")
|
|
|
|
|
Hi,
I have a gui application. Originally the application is written such that all of the processing is done when you receive the OnIdle message. The performance was adequate and both the GUI and the process got enough resources such that the interface worked ok. I decided that it made more sense to move the processing from OnIdle into a separate thread in order to improve performance of the user interface. Unfortunately the opposite happened. Now the GUI is almost dead.
Here's a model of my program:
<br />
UINT Hog(LPVOID p)<br />
{<br />
CThreadView * me = (CThreadView *) p;<br />
return me->MyHog();<br />
}<br />
<br />
UINT CThreadView::MyHog()<br />
{<br />
int x = 0;<br />
while(1)<br />
{<br />
x = x*x;<br />
}<br />
return 0;<br />
}...<br />
AfxBeginThread(Hog, this);<br />
...<br />
First, that's a model, that's not my processing function. Second, there is A LOT of performance improvement if the thread is allowed to run without calling this->Invalidate(). But I need to update the graphical user interface based on what the thread has done. That is I need to repaint the CView.
I've also used SendMessage() (yes I'm aware of deadlock possibility) and PostMessage() to run a function in the "main" thread that just calls this->Invalidate. The performance sucks as well.
I don't have any critical sections/locks on the data so I don't think anyone is waiting.
Any suggestions?
|
|
|
|
|
Can't you just update the GUI in OnIdle as you did before?
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
Want a Boost forum in Code Project? Vote here[^]!
|
|
|
|
|
Any time you spin in a tight loop in a worker thread, it will suck up as much CPU time as the system will give it. Look in Task Manager and you'll see the CPU pegged.
And since that thread is doing so much work, it ends up posting a ton of messages to the main thread (via Invalidate() , which generates WM_ERASEBKGND , WM_NCPAINT , and WM_PAINT , maybe others too). Since the thread is hogging the CPU, the main thread can't process those messages as quickly as if the thread weren't running.
--Mike--
Personal stuff:: Ericahist | Homepage
Shareware stuff:: 1ClickPicGrabber | RightClick-Encrypt
CP stuff:: CP SearchBar v2.0.2 | C++ Forum FAQ
----
Ford, what's this fish doing in my ear?
|
|
|
|
|
First of all: lower the priority of your worker thread. Any thread that will take a long time to process data should be low priority so that it doesn't interupt anything else you might want to do while waiting. (such as play a game!) This will at least make sure your GUI thread isn't interupted when it need to do something.
The idea is that for any process that takes a long time, it makes little difference in the long run if other processes interupt it. However, for interactive processes (which normally don't take a long time to run) anything else running will slow it down. So you make your worker threads low priority and it has little effect on them, while it makes the rest of the system seem faster! This comes from scheduler theory, but most CS programs don't require a class that would cover it.
Some ideas: I don't know which is best, if any. Some are sub optimal. Some might not even work.
Instead of sending events, just have your GUI thread repaint on a timer every second.
Have the GUI thread wait on a semophore that your worker thread normally hold. This is hard to describe, basicly you need a way to force the GUI thread to wait until the worker thread has done something before it repaints. You might need a third thread to watch the semaphore and send the message, I can't recall how the API works.
Instead of a full repaint, send a message detailing the progress, and just update the parts of the GUI that change based on status.
In the worker thread only update the GUI every 100 (1000? experiment on different machines to find a good number) iterations through the loop.
|
|
|
|
|
Along with the suggestions already made...
Why invalidate the entire window?
Are you udpating a graph? Can you just redraw the part that changed?
Does your data change that fast? If so, maybe you can not keep up with it visually anyway. You will need to show a 'summary' of some form. Or historize the dat and allow user to select which time frame/ranges he wants to view.
|
|
|
|
|
Thank you for all the suggestions. I'm trying out some of them now. Setting the thread priority to below normal helps, but then when I move the mouse or interact with the gui the thread almost doesn't do anything.
To give you more detail the program is actually capturing images using a camera via a firewire cable. With thread having normal priority the images come in really fast, so fast that the user interface is unusable and the images don't get displayed properly.
I redraw using OpenGL, and I no longer call Invalidate() I just call the GL function that draws the image. The performance is still not as good as the balance I have now from OnIdle.
|
|
|
|
|