• ### What is your GameDev Story?

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

## 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)
{
//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


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 on other sites
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 on other sites

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 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 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 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 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 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 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 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. ;)

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

(You must login to your GameDev.net account.)

• 12
• 11
• 15
• 11
• 11
• ### Forum Statistics

• Total Topics
634149
• Total Posts
3015835
×