tengo una función:ventana de Creación en otro hilo (no hilo principal)
HWND createMainWindow(P2p_Socket_Machine * toSend){
HWND hMainWnd = CreateWindow(
L"Class",/*(LPCWSTR) nameOfConference.c_str()*/L"Chat", WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU,
CW_USEDEFAULT, 0, 600,400,
(HWND)NULL, (HMENU)NULL,
/*(HINSTANCE)hlnstance*/NULL, NULL
);
if (!hMainWnd) {
MessageBox(NULL, L"Cannot create main window", L"Error", MB_OK);
return 0;
}
CreateWindowA("LISTBOX",NULL, WS_CHILD|WS_VISIBLE|WS_BORDER|WS_VSCROLL|LBS_NOTIFY|LBS_MULTIPLESEL,310,30,255,275,hMainWnd,(HMENU)List_Box,NULL,NULL);
CreateWindowExA(NULL,"BUTTON", "Refresh", WS_TABSTOP|WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON,385,310,100,24,hMainWnd,(HMENU)Button_Refresh, NULL ,NULL);
CreateWindowExA(NULL,"BUTTON", "Send", WS_TABSTOP|WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON,385,334,100,24,hMainWnd,(HMENU)Button_Send, NULL ,NULL);
CreateWindowExA(NULL,"BUTTON", "New", WS_TABSTOP|WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON,385,354,100,24,hMainWnd,(HMENU)Button_New, NULL ,NULL);
CreateWindowA("EDIT",0,WS_BORDER|WS_VISIBLE|WS_CHILD|ES_LEFT|ES_MULTILINE|WS_VSCROLL|WS_DISABLED,
10,30,265,275,hMainWnd,(HMENU)Text_Box_Get,NULL,NULL);
CreateWindowA("EDIT",0,WS_BORDER|WS_VISIBLE|WS_CHILD|ES_LEFT|ES_MULTILINE|WS_VSCROLL,
10,320,265,45,hMainWnd,(HMENU)Text_Box_Send,NULL,NULL);
SetWindowLongPtr(hMainWnd,GWLP_USERDATA,(LONG_PTR)toSend);
ShowWindow(hMainWnd, SW_SHOW);
//UpdateWindow(hMainWnd);
return hMainWnd;
}
Y esto es parte principal de mi programa:
int WINAPI WinMain(HINSTANCE hlnstance, HINSTANCE hPrevInstance, LPSTR IpCmdLine, int
nCmdShow)
{
WNDCLASSEX wc;
wc.cbSize = sizeof(wc);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MyFunc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hlnstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = L"Class";
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
HWND toSend = createMainWindow(P2pSocket);
//some code
hThread = CreateThread(NULL, 0, ClientThread,
Message2, 0, &dwThreadId);
if (hThread == NULL)
{
cout<<"Create thread filed";
exit(10);
}
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
cuando llame a la función createMainWindow() en la parte principal de mi programa funciona como debería, pero cuando lo ejecuto en mi hilo (ClientThread) no funciona. He leído que debería crear ventanas solo en el hilo principal. ¿Es verdad? Y si es cierto, ¿cuál es la forma más sencilla de llamar a esta función desde otro lado para que se haga en el hilo principal?
Gracias a todos. Ahora sé el problema, pero estoy atascado con la solución. Mi código hilo de cliente es:
while(1){
vector<HWND> AllHandlers;
pair<string,string> Answer = Pointer->receiveMsgByUdp();
if(!Pointer->isMyLocalAddress(Answer.first)){
int type = messageUdpContentType(Answer.second);
switch(type){
case 0 :
Pointer->sendMsgToIpUdp(Answer.first,"<?xml version='1.0'?><accepted/>");
AllHandlers = getAllHandlersOfElementsOnWindowsByIdentityCode(Pointer->getAllHandlers(),List_Box);
for(vector<HWND>::iterator j = AllHandlers.begin();j!=AllHandlers.end();j++)
if(SendMessageA(*j, LB_FINDSTRINGEXACT, 0, (LPARAM)Answer.first.c_str())==LB_ERR)
SendMessageA(*j, LB_ADDSTRING, 0, (LPARAM)Answer.first.c_str());
break;
case 1 :
AllHandlers = getAllHandlersOfElementsOnWindowsByIdentityCode(Pointer->getAllHandlers(),List_Box);
for(vector<HWND>::iterator j = AllHandlers.begin();j!=AllHandlers.end();j++)
if(SendMessageA(*j, LB_FINDSTRINGEXACT, 0, (LPARAM)Answer.first.c_str())==LB_ERR)
SendMessageA(*j, LB_ADDSTRING, 0, (LPARAM)Answer.first.c_str());
break;
case 2 :
AllHandlers = getAllHandlersOfElementsOnWindowsByIdentityCode(Pointer->getAllHandlers(),List_Box);
for(vector<HWND>::iterator j = AllHandlers.begin();j!=AllHandlers.end();j++)
if((i = SendMessageA(*j, LB_FINDSTRINGEXACT, 0, (LPARAM)Answer.first.c_str()))!=LB_ERR)
SendMessageA(*j,LB_DELETESTRING, 0, (LPARAM)Answer.first.c_str());
break;
case 3 :
userReply = MessageBoxW(NULL, L"Принять приглашение на конференцию?",
L"", MB_YESNO | MB_ICONQUESTION);
if (userReply==IDYES){
//todo: Проверка на создание встречи, в которой уже состоишь
string nameOfConf = fetchNameOfInviteConf(Answer.second);
Pointer->createConference(nameOfConf);
HWND toSendTo = createMainWindow(Pointer);
Pointer->setHandlerInfo(nameOfConf,toSendTo);
Pointer->addNewMemberToConference_ServerType(nameOfConf,Answer.first);
string toSend = string("<?xml version='1.0'?><inviteAccepted>") + nameOfConf + string("</inviteAccepted>");
Pointer->sendMsgToIpUdp(Answer.first,toSend);
}
break;
case 4 :
string nameOfConf = fetchNameOfInviteAcceptConf(Answer.second);
toSend.clear();
Participants.clear();
Participants = Pointer->getCurrentParticipants(nameOfConf);
toSend+="<?xml version='1.0'?>";
toSend+="<conference>";
toSend+="<nameOfConference>";
toSend+=nameOfConf;
toSend+="</nameOfConference>";
for(vector<string>::iterator i = Participants.begin();i!=Participants.end();i++){
toSend+="<participant>" + *i + "</participant>";
}
toSend+="</conference>";
Pointer->addNewMemberToConference_ClientType(nameOfConf,Answer.first);
Pointer->sendToIpTcp(Answer.first,toSend);
break;
}
la receiveMsgByUdp función() deja este hilo hasta que recibe el mensaje. Me disculpo por la falta de conocimiento, pero qué funciones puedo usar u otras cosas para resolver esto. ¿Debería reescribir mi método receiveMsgByUdp() para que sea asíncrono o cómo puedo llamar a la función createMainWindow() para ejecutar en el hilo principal? Acerca de la última variante: cómo puedo hacer esto en winapi puro, no pude encontrar ningún ejemplo simple. ¿Alguien puede dar un fragmento de código? Gracias una vez más)
Gracias a todos.Logré hacer que este programa funcione. utilicé el método de David Heffernan. Y la información en este enlace http://stackoverflow.com/questions/7060686/how-do-i-sendmessage-to-a-window-created-on-another-thread~~V~~singular~~3rd – knightOfSpring