Jump to content
  • Advertisement
Sign in to follow this  
GetWindowRect

Multi Threading?

This topic is 4813 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am not quite sure what I have done wrong, but I have a window wrapper class to create windows. I create a new window class in a button click which then freezes both window's. I have used the same code in other programs and I have not ran into this problem. I am thinking that the message loop freezes the first window's message loop because the new window starts a message loop in the WM_COMMAND message. I am not quite sure, if that is the case, why it only does it in this application and not others, but it makes sense. Anyway, I tried to make a thread to call the new window creation and I am getting the following error: error C2664: 'CreateThread' : cannot convert parameter 3 from 'int (LPVOID)' to 'LPTHREAD_START_ROUTINE'
//Client is my class that inherits from the Window class.
		DWORD WINAPI ThreadProc(LPVOID lpParameter)
		{
			//LPTHREAD_START_ROUTINE
			//Open the Client form in a new thread.
			frmClient = new Client("wInternetClient", "Internet Test - Client");
			frmClient->Position(225, 225); 
			frmClient->Size(220, 100);
			frmClient->Style = WS_BORDER | WS_CAPTION;
			frmClient->StyleEx = WS_EX_STATICEDGE;
			frmClient->BackColor(212, 208, 200);
			frmClient->Show();
		}


//In the WM_COMMAND for the connect button I have the following line to create the thread
hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, 999);

I am not sure if I am doing something wrong somewhere, but if anyone can help, or point me in the right direction, I would appreciate it greatly. If more code is required I would be happy to post more.

Share this post


Link to post
Share on other sites
Advertisement
Well, for the issue this all started with, I was creating a timer with SetTimer() right before creating the window. When I comment it out, everything runs fine. If I put the form in front of the SetTimer() function call does not get called until after I close the client form. I think threading is about the only way I can go about fixing this, but who knows I am wrong a lot. I still cannot figure out why I cannot run the thread. On MSDN they create a ThreadProc function with the same return value and parameter, and call CreateThread in the same manner as I am. However, I get the error as posted above. Thanks in advance.

Share this post


Link to post
Share on other sites
Try this instead:


DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
//LPTHREAD_START_ROUTINE
//Open the Client form in a new thread.
frmClient = new Client("wInternetClient", "Internet Test - Client");
frmClient->Position(225, 225);
frmClient->Size(220, 100);
frmClient->Style = WS_BORDER | WS_CAPTION;
frmClient->StyleEx = WS_EX_STATICEDGE;
frmClient->BackColor(212, 208, 200);
frmClient->Show();

return ((DWORD)lpParameter);

}




That might work.

Share this post


Link to post
Share on other sites
Thank you for the reply, I was too caught up in the error to remember to put the return value. However, it did not fix the problem, I am still getting:
error C2664: 'CreateThread' : cannot convert parameter 3 from 'DWORD (LPVOID)' to 'LPTHREAD_START_ROUTINE'

I think it was originally int(LPVOID) now it is back to DWORD. I appreciate the thought though, thanks again.

Share this post


Link to post
Share on other sites
I was reading up a little more on threads and I saw that CreateThread and CloseHandle can have problems and cause memory leaks. The recommended alternative was _beginthreadex(). However, in order to use it, you have to include <process.h>. I include the file, yet now I get the error:
error C3861: '_beginthreadex': identifier not found, even with argument-dependent lookup

I cannot find anywhere that I need to include a .lib file or anything, only the header. I think I will keep looking into this version rather than the alternate CreateThread method.

Share this post


Link to post
Share on other sites
I've never had any problems with CreateThread. Just type cast it:

CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadProc,NULL,0,&someInt);


And I read that "small memory leak advisory" they talk about in the Win32 API, but I'm using two threads, both of which call fread from the standard C libraries, and no memory leaks. Not even small ones. ;)

Just don't call ExitThread. Let the thread run out, or put a boolean to tell the thread to "exit" by passing it through the parameter. Either way, never order the thread to exit.

Share this post


Link to post
Share on other sites
Thank you very much for your reply Nychold: I did try to cast the function to LPTHREAD_START_ROUTINE, it gave me an error telling me I could not convert the function to it.

error C2440: 'type cast' : cannot convert from 'overloaded-function' to 'LPTHREAD_START_ROUTINE'

Thank you for the thought though.

Share this post


Link to post
Share on other sites
After looking over my code, pull that WINAPI out of there, and it should work fine.

Errr, wait a minute. Are you overloading the identifier "ThreadProc"? If so, I would say don't do it. It won't know which address to pass.

Share this post


Link to post
Share on other sites
I don't think I am overloading it, and if I am, I am not doing it on purpose. Could it be thinking that I am because it is in a class? (probably dumb question).

Is there a ThreadProc function already created or something? Sorry for the silly questions, I am just pretty confused.

Share this post


Link to post
Share on other sites
Yep, that'll do it. See, every call from a class has a "hidden" parameter in it, which carries "this" information. That's how C++ knows where it is. The only way to get around this is to make it static, and pass as a parameter your class. Here's (one of) mine:


//...inside TAudioObject

hLoad=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)threadLoad,
this,0,&threadID);
//...
static DWORD threadLoad(void *param)
{
TAudioObject *obj=(TAudioObject *)param;

// Thread must load 1 buffer, set the ready state
// and continue to load the other buffers with a
// short sleep state (50 milliseconds) between loads

alSourcei(obj->sourceID,AL_LOOPING,AL_FALSE);

for (int i=0;i<BUFFER_COUNT;i++)
{
switch (obj->type)
{
case AUDIO_WAV:
obj->StreamWAV(obj->bufferID);
break;

case AUDIO_OGG_VORBIS:
obj->StreamOGG(obj->bufferID);
break;
}
alSourceQueueBuffers(obj->sourceID,1,&obj->bufferID);
obj->ready=true;
SleepEx(100,true);
}
obj->hLoad=NULL;
obj->threadID=0;
return 0;
};




And no, it's not silly. I've been in a similar situation before numerous times. ;)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!