Windows.c (18811B)
1 #define WINVER 0x500 2 #define _WIN32_IE WINVER 3 #define _WIN32_WINNT WINVER 4 #define NTDDI_VERSION NTDDI_VISTA 5 #define UNICODE 6 #define WIN32_LEAN_AND_MEAN 7 #include <EGong/Util/Config_Compiletime.h> 8 #include <EGong/Util/Config.h> 9 #include <EGong/Interfaces.h> 10 #include <EGong/Util/Array.h> 11 #include <EGong/Interfaces/Windows.h> 12 #include <EGong/Util/Waiter.h> 13 #include <winsock2.h> 14 #include <EGong/Interfaces/GUI.h> 15 #include <EGong/Main.h> 16 #include <EGong/CNC.h> 17 #include <EGong/Util/Log.h> 18 #include <windows.h> 19 #include <windowsx.h> 20 #include <shellapi.h> 21 #include <stdlib.h> 22 struct EGong_if_ptrtbl EGong_if_win_ptrtbl={ 23 .setup=&EGong_if_win_setup, 24 .cycle=&EGong_if_win_cycle, 25 .display=&EGong_if_win_display, 26 .shutdown=&EGong_if_win_shutdown, 27 .sock_watch=&EGong_if_win_waiter_add, 28 .loop=&EGong_if_win_loop 29 }; 30 extern struct EGong_GUI_item EGong_if_win_messagegui; 31 struct EGong_GUI_item EGong_if_win_messagegui_button={.type=EGONG_GUI_BUTTON, .text=GUIT("OK"), .tooltip=NULL, .child=NULL, .events=EEV_ARR{ 32 EEV_EL{.command={.type={.type=EGONG_COMMAND_FUNC_VOID, .args=1}, .pointer=&EGong_if_win_destroy}, .sources=EES_ARR{ 33 EES_EL{.type=EGONG_GUI_EVSRC_ELEMENT, .data=&EGong_if_win_messagegui}, 34 EES_FIN 35 }}, 36 EEV_FIN 37 }}; 38 struct EGong_GUI_item EGong_if_win_messagegui_text={.type=EGONG_GUI_LABEL, .text=GUIT(""), .tooltip=NULL, .child=NULL}; 39 struct EGong_GUI_item EGong_if_win_messagegui={.type=EGONG_GUI_WINDOW, .extra=(void *)10, .text=GUIT("EGong Nachricht"), .tooltip=NULL, .child=EGUI_ARR{ 40 EGUI_EL{.type=EGONG_GUI_VBOX, .extra=(void *)10, .text=NULL, .tooltip=NULL, .child=EGUI_ARR{ 41 EGUI_ELX(EGong_if_win_messagegui_text), 42 EGUI_ELX(EGong_if_win_messagegui_button), 43 EGUI_FIN 44 }}, 45 EGUI_FIN 46 }}; 47 WNDCLASSW EGong_if_win_getmsg = {0}; 48 HWND EGong_if_win_root=NULL; 49 HINSTANCE EGong_if_win_instance=NULL; 50 struct EGong_GUI_item *EGong_if_win_global_systray=NULL; 51 struct Array EGong_if_win_menus; 52 struct Array EGong_if_win_windows; 53 HWND EGong_if_win_create_wrapper(struct EGong_GUI_item *parent, struct EGong_GUI_item *this){ 54 EGong_if_win_create(parent, this, 0); 55 } 56 RECT EGong_if_win_getsize(struct EGong_GUI_item *this, unsigned short int recurse){ 57 HDC hdc=GetDC(NULL); 58 RECT rect={0,0,0,0}; 59 RECT childr; 60 unsigned int i; 61 switch(this->type){ 62 case EGONG_GUI_WINDOW: 63 for(i=0; this->child[i]!=NULL&&recurse; i++){ 64 childr=EGong_if_win_getsize(this->child[i], recurse); 65 if(childr.right>rect.right){ 66 rect.right=childr.right; 67 } 68 if(childr.bottom>rect.bottom){ 69 rect.bottom=childr.bottom; 70 } 71 } 72 rect.right+=2*(unsigned int)(uintptr_t)this->extra; 73 rect.bottom+=2*(unsigned int)(uintptr_t)this->extra; 74 break; 75 case EGONG_GUI_TEXT: 76 DrawText(hdc, GUIT("M"), 1, &rect, DT_CALCRECT); 77 rect.right*=(unsigned int)this->extra; 78 rect.right+=5; 79 rect.bottom+=5; 80 break; 81 case EGONG_GUI_LABEL: 82 DrawText(hdc, this->text, 1, &rect, DT_CALCRECT); 83 break; 84 case EGONG_GUI_TOGGLE_BUTTON: 85 case EGONG_GUI_BUTTON: 86 DrawText(hdc, this->text, -1, &rect, DT_CALCRECT); 87 rect.right+=10; 88 rect.bottom+=10; 89 break; 90 case EGONG_GUI_HBOX: 91 for(i=0; this->child[i]!=NULL&&recurse; i++){ 92 childr=EGong_if_win_getsize(this->child[i], recurse); 93 rect.right+=childr.right+(unsigned int)this->extra; 94 if(childr.bottom>rect.bottom){ 95 rect.bottom=childr.bottom; 96 } 97 } 98 break; 99 case EGONG_GUI_VBOX: 100 for(i=0; this->child[i]!=NULL&&recurse; i++){ 101 childr=EGong_if_win_getsize(this->child[i], recurse); 102 rect.bottom+=childr.bottom+(unsigned int)this->extra; 103 if(childr.right>rect.right){ 104 rect.right=childr.right; 105 } 106 } 107 break; 108 default: 109 do_log("Item has no real size", LOG_TYPE_NORMAL, LOG_LEVEL_WARNING); 110 break; 111 } 112 return rect; 113 } 114 HWND EGong_if_win_create(struct EGong_GUI_item *parent, struct EGong_GUI_item *this, unsigned int child){ 115 HWND element=NULL; 116 HINSTANCE hInstance; 117 NOTIFYICONDATA *notify; 118 MENUITEMINFO *menu; 119 RECT dimensions, *parentd; 120 HDC hdc; 121 unsigned int i; 122 unsigned int tmp; 123 struct EGong_GUI_item **children=this->child; 124 if(parent!=this){ 125 if(this->type==EGONG_GUI_TEXT||this->type==EGONG_GUI_BUTTON||this->type==EGONG_GUI_TOGGLE_BUTTON||this->type==EGONG_GUI_HBOX||this->type==EGONG_GUI_VBOX||this->type==EGONG_GUI_LABEL){ 126 dimensions=EGong_if_win_getsize(this, 1); 127 if(parent->type==EGONG_GUI_HBOX||parent->type==EGONG_GUI_VBOX){ 128 parentd=parent->userdata; 129 dimensions.top=parentd->top; 130 dimensions.left=parentd->left; 131 if(parent->type==EGONG_GUI_HBOX){ 132 dimensions.top+=(parentd->bottom-dimensions.bottom)/2; 133 parentd->left+=dimensions.right+(unsigned int)parent->extra; 134 } 135 else{ 136 dimensions.left+=(parentd->right-dimensions.right)/2; 137 parentd->top+=dimensions.bottom+(unsigned int)parent->extra; 138 } 139 } 140 else if(parent->type==EGONG_GUI_WINDOW){ 141 dimensions.top=dimensions.left=(unsigned int)parent->extra; 142 } 143 } 144 switch(this->type){ 145 case EGONG_GUI_WINDOW: 146 hInstance=(HINSTANCE)GetWindowLong( GetForegroundWindow(), GWL_HINSTANCE ); 147 dimensions=EGong_if_win_getsize(this, 1); 148 dimensions.right+=2*GetSystemMetrics(SM_CXSIZEFRAME); 149 dimensions.bottom+=2*GetSystemMetrics(SM_CYSIZEFRAME)+GetSystemMetrics(SM_CYSIZE); 150 element=CreateWindow(EGong_if_win_getmsg.lpszClassName, this->text, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, dimensions.right+(unsigned int)this->extra, dimensions.bottom+(unsigned int)this->extra, 0, 0, hInstance, 0); 151 break; 152 case EGONG_GUI_TEXT: 153 element=CreateWindow(L"Edit", this->text, WS_VISIBLE | WS_CHILD | WS_BORDER | ES_AUTOHSCROLL, dimensions.left, dimensions.top, dimensions.right, dimensions.bottom, parent->itemptr, (HMENU) child, NULL, NULL); 154 break; 155 case EGONG_GUI_BUTTON: 156 element=CreateWindow(L"Button", this->text, WS_VISIBLE | WS_CHILD, dimensions.left, dimensions.top, dimensions.right, dimensions.bottom, parent->itemptr, (HMENU) child, NULL, NULL); 157 break; 158 case EGONG_GUI_TOGGLE_BUTTON: 159 element=CreateWindow(L"Button", this->text, WS_VISIBLE | WS_CHILD | BS_CHECKBOX , dimensions.left, dimensions.top, dimensions.right, dimensions.bottom, parent->itemptr, (HMENU) child, NULL, NULL); 160 break; 161 case EGONG_GUI_MENUITEM: 162 case EGONG_GUI_MENUITEM_IMAGE: 163 case EGONG_GUI_MENUITEM_SEPARATOR: 164 tmp=MF_BYPOSITION; 165 if(this->type==EGONG_GUI_MENUITEM_SEPARATOR){ 166 tmp|=MF_SEPARATOR; 167 } 168 else{ 169 tmp|=MF_STRING; 170 } 171 if(children!=NULL){ 172 HMENU submenu=CreatePopupMenu(); 173 for(i=0; children[i]!=NULL; i++){ 174 if(children[i]->type==EGONG_GUI_MENUITEM || children[i]->type==EGONG_GUI_MENUITEM_IMAGE || children[i]->type==EGONG_GUI_MENUITEM_SEPARATOR){ 175 tmp|=MF_POPUP; 176 } 177 } 178 if((tmp&MF_POPUP)>0){ 179 this->userdata=submenu; 180 InsertMenu(parent->itemptr, -1, tmp, (UINT) submenu, this->text); 181 } 182 else{ 183 this->userdata=NULL; 184 DestroyMenu(submenu); 185 } 186 } 187 if((tmp&MF_POPUP)==0){ 188 if(parent->type==EGONG_GUI_MENUITEM||parent->type==EGONG_GUI_MENUITEM_IMAGE){ 189 InsertMenu(parent->userdata, -1, tmp, EGong_if_win_menus.element_count+1, this->text); 190 } 191 else{ 192 InsertMenu(parent->itemptr, -1, tmp, EGong_if_win_menus.element_count+1, this->text); 193 } 194 Array_add(&EGong_if_win_menus, &this); //Save menus for identification. 195 } 196 element=parent->itemptr; 197 break; 198 case EGONG_GUI_MENU: 199 element=(HWND)CreatePopupMenu(); 200 break; 201 case EGONG_GUI_LABEL: 202 element=CreateWindow(L"Static", this->text, WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER, dimensions.left, dimensions.top, dimensions.right, dimensions.bottom, parent->itemptr, (HMENU) child, NULL, NULL); 203 204 break; 205 case EGONG_GUI_HBOX: 206 case EGONG_GUI_VBOX: 207 this->userdata=malloc(sizeof(RECT)); 208 memcpy(this->userdata, &dimensions, sizeof(RECT)); 209 element=parent->itemptr; 210 break; 211 case EGONG_GUI_SYSTRAY: 212 hInstance=(HINSTANCE)GetWindowLong( GetForegroundWindow(), GWL_HINSTANCE ); 213 if(EGong_if_win_global_systray!=NULL){ 214 do_log("Already a systray icon defined!", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR); 215 return NULL; 216 } 217 notify=malloc(sizeof(NOTIFYICONDATA)); 218 if(parent==NULL){ 219 if(EGong_if_win_root==NULL){ 220 notify->hWnd=CreateWindow(EGong_if_win_getmsg.lpszClassName, NULL, 0, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0, 0, hInstance, 0); 221 EGong_if_win_root=notify->hWnd; 222 } 223 else{ 224 notify->hWnd=EGong_if_win_root; 225 } 226 227 } 228 else{ 229 notify->hWnd=parent->itemptr; 230 } 231 element=notify->hWnd; 232 notify->cbSize = sizeof(NOTIFYICONDATA); 233 234 notify->uID=12+1; 235 notify->uFlags=NIF_ICON | NIF_MESSAGE; 236 notify->uCallbackMessage=WM_TRAY_ACTION; 237 notify->hIcon=LoadImage(GetModuleHandle(NULL), GUIT("Master_icon"), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE); 238 if(notify->hIcon==NULL){ 239 do_log("Couldn't load Icon", LOG_TYPE_SIGNAL, LOG_LEVEL_ERROR); 240 } 241 242 #if _WIN32_IE >= 0x0500 243 notify->uVersion=NOTIFYICON_VERSION; 244 #endif 245 if(this->tooltip!=NULL){ 246 wcscpy(notify->szTip, this->tooltip); 247 notify->uFlags|=NIF_TIP; 248 } 249 Shell_NotifyIcon(NIM_ADD, notify); 250 #if _WIN32_IE >= 0x0500 251 Shell_NotifyIcon(NIM_SETVERSION, notify); 252 #endif 253 this->userdata=notify; 254 EGong_if_win_global_systray=this; 255 break; 256 default: 257 do_log("Unknown GUI-Type specified", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR); 258 return NULL; 259 } 260 } 261 else{ 262 element=this->itemptr; 263 } 264 if(element==NULL){ 265 do_log("Could not initialize GUI Element", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR); 266 return NULL; 267 } 268 if((parent!=NULL && parent->itemptr!=element) && !(this->type==EGONG_GUI_SYSTRAY || this->type==EGONG_GUI_MENU || this->type==EGONG_GUI_MENUITEM || this->type==EGONG_GUI_MENUITEM_SEPARATOR || this->type==EGONG_GUI_LABEL)){ //if parent->itemptr==element, the item does not exist. 269 if(SetWindowLongPtr(element, GWLP_USERDATA, (LONG_PTR)this)==(LONG_PTR)NULL&&GetLastError()!=0){ 270 do_log("Couldn't set userpointer", LOG_TYPE_SIGNAL, LOG_LEVEL_ERROR); 271 } 272 } 273 if(parent==NULL && EGong_if_win_root==NULL){ 274 EGong_if_win_root=element; 275 } 276 this->itemptr=element; 277 if(parent==NULL){ 278 Array_add(&EGong_if_win_windows, &this); //Save rootwindows for destruction 279 } 280 if(children!=NULL){ 281 for(i=0; children[i]!=NULL; i++){ 282 EGong_if_win_create(this, children[i], i); 283 } 284 } 285 return element; 286 } 287 void EGong_if_win_show_element(struct EGong_GUI_item *itm){ 288 switch(itm->type){ 289 case EGONG_GUI_WINDOW: 290 case EGONG_GUI_MENU: 291 EGong_if_win_show_item((HWND) itm->itemptr); 292 break; 293 } 294 } 295 296 void EGong_if_win_show_item(HWND item){ 297 ShowWindow(item, SW_SHOW); 298 SetForegroundWindow(item); 299 } 300 301 void EGong_if_win_free_item_value(struct EGong_GUI_item *item, void *value){ 302 do_log("Guessing type", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG); 303 switch(item->type){ 304 case EGONG_GUI_TEXT: 305 free(value); 306 break; 307 default: 308 do_log("Nothing to do...", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG); 309 } 310 } 311 void *EGong_if_win_get_item_value(struct EGong_GUI_item *item){ 312 void *ret=NULL; 313 size_t len; 314 315 switch(item->type){ 316 case EGONG_GUI_TEXT: 317 len=Edit_GetTextLength(item->itemptr)+1; 318 wchar_t *text=calloc(len, sizeof(wchar_t)); 319 char *msg=calloc(len, sizeof(char)); 320 321 Edit_GetText(item->itemptr, text, len); 322 size_t bytes=wcstombs(msg, text, len); 323 if(bytes==-1){ 324 do_log("Couldn't convert widecharstring to multibytestring", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR); 325 free(text); 326 free(msg); 327 break; 328 } 329 msg[bytes]='\0'; 330 ret=(void *)msg; 331 332 free(text); 333 break; 334 case EGONG_GUI_TOGGLE_BUTTON: 335 ret=(void *)(intptr_t)(unsigned int)(((Button_GetState(item->itemptr)&BST_PUSHED)>0) ? 1 : 0); 336 break; 337 case EGONG_GUI_WINDOW: 338 ret=(void *)item->itemptr; 339 break; 340 default: 341 do_log("Event datasource specified where no data can be obtained", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR); 342 break; 343 } 344 return ret; 345 } 346 void EGong_if_win_toggle_item(struct EGong_GUI_item *item){ 347 if(IsWindowVisible(item->itemptr)){ 348 ShowWindow(item->itemptr, SW_HIDE); 349 } 350 else{ 351 EGong_if_win_show_element(item); 352 } 353 } 354 void EGong_if_win_trayhandler(struct EGong_GUI_item *item, unsigned short int type, int x, int y, HWND hwnd){ 355 unsigned int i=0; 356 for(i=0; item->child[i]!=NULL; i++){ 357 if(item->child[i]->type==type){ 358 if(type==EGONG_GUI_MENU){ 359 SetForegroundWindow(EGong_if_win_root); 360 int rightaligned=(GetSystemMetrics(SM_MENUDROPALIGNMENT)==0) ? TPM_LEFTALIGN : TPM_RIGHTALIGN; 361 int menu=TrackPopupMenu(item->child[i]->itemptr, rightaligned | TPM_TOPALIGN | TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, x, y, 0, hwnd, NULL); 362 if(menu==0){ 363 continue; 364 } 365 menu--; 366 struct EGong_GUI_item *win=*(struct EGong_GUI_item **)Array_get(&EGong_if_win_menus, menu); 367 EGong_if_win_actionhandler(win); 368 } 369 else{ 370 EGong_if_win_toggle_item(item->child[i]); 371 } 372 } 373 } 374 } 375 void EGong_if_win_actionhandler(struct EGong_GUI_item *item){ 376 if(item->events==NULL) 377 return; 378 do_log("We have action!1", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG); 379 unsigned int i=0; 380 for(i=0; item->events[i]!=NULL; i++){ 381 EGong_GUI_event_callback(item, item->events[i]); 382 } 383 384 } 385 386 LRESULT CALLBACK EGong_if_win_callback(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){ 387 struct EGong_GUI_item *win=NULL; 388 POINT pt; 389 switch(msg){ 390 case WM_COMMAND: 391 /* 392 if(isMenuItem){ 393 win=Array_get(&EGong_if_win_menus, LOWORD(wParam)); 394 } 395 else{ 396 397 } 398 */ 399 win=(struct EGong_GUI_item *)GetWindowLongPtr((HWND)lParam, GWLP_USERDATA); 400 if(win!=NULL){ 401 EGong_if_win_actionhandler(win); 402 } 403 break; 404 405 case WM_TRAY_ACTION: 406 switch(lParam){ 407 case WM_LBUTTONDOWN: 408 case WM_RBUTTONDOWN: 409 GetCursorPos(&pt); 410 if(lParam==WM_LBUTTONDOWN){ 411 EGong_if_win_trayhandler(EGong_if_win_global_systray, EGONG_GUI_WINDOW, pt.x, pt.y, hwnd); 412 } 413 else{ 414 EGong_if_win_trayhandler(EGong_if_win_global_systray, EGONG_GUI_MENU, pt.x, pt.y, hwnd); 415 } 416 break; 417 } 418 break; 419 case WM_CLOSE: 420 ShowWindow(hwnd, SW_HIDE); 421 return 0; 422 break; 423 case WM_DESTROY: 424 case WM_QUIT: 425 EGong_main_deinit(); 426 exit(LOWORD(wParam)); 427 break; 428 } 429 return DefWindowProcW(hwnd, msg, wParam, lParam); 430 } 431 432 433 int EGong_if_win_setup(struct EGong_interface *interface){ 434 do_log("Initializing WinGUI", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG); 435 436 HINSTANCE hInstance = (HINSTANCE)GetWindowLong( GetForegroundWindow(), GWL_HINSTANCE ); 437 EGong_if_win_getmsg.lpszClassName = L"EGong"; 438 EGong_if_win_getmsg.hInstance = hInstance; 439 EGong_if_win_getmsg.hbrBackground = GetSysColorBrush(COLOR_3DFACE); 440 EGong_if_win_getmsg.lpfnWndProc = EGong_if_win_callback; 441 EGong_if_win_getmsg.hCursor = LoadCursor(0,IDC_ARROW); 442 RegisterClassW(&EGong_if_win_getmsg); 443 444 Array_init(&EGong_if_win_menus, sizeof(struct EGong_GUI_item *), 0); 445 Array_init(&EGong_if_win_windows, sizeof(struct EGong_GUI_item *), 2); 446 447 return EGONG_INTERFACE_RETURN_OK; 448 } 449 450 int EGong_if_win_cmd(char *msg){ 451 return EGONG_INTERFACE_RETURN_OK; 452 } 453 454 int EGong_if_win_cycle(struct EGong_interface *interface, String *msg, char **dest){ 455 MSG loopmsg; 456 while(PeekMessage(&loopmsg, NULL, 0, 0, PM_REMOVE)!=0){ 457 TranslateMessage(&loopmsg); 458 DispatchMessage(&loopmsg); 459 } 460 return EGONG_INTERFACE_RETURN_OK; 461 } 462 463 int EGong_if_win_display_notify(struct EGong_interface *interface, const String *msg){ 464 NOTIFYICONDATA *nid=EGong_if_win_global_systray->userdata; 465 mbstowcs(nid->szInfo, msg->data, msg->length); 466 nid->szInfo[msg->length]='\0'; 467 nid->uFlags=NIF_INFO; 468 #if _WIN32_IE >= 0x0500 469 nid->uTimeout=5000; 470 #endif 471 wcscpy(nid->szInfoTitle, L"EGong Nachricht"); 472 #if _WIN32_IE > 0x0500 473 //nid->dwInfoFlags=NIIF_USER; 474 nid->dwInfoFlags=NIIF_NONE; 475 #else 476 nid->dwInfoFlags=NIIF_NONE; 477 #endif 478 479 if(!Shell_NotifyIconW(NIM_MODIFY, nid)){ 480 do_log("Couldn't notify via Systray", LOG_TYPE_SIGNAL, LOG_LEVEL_ERROR); 481 return EGONG_INTERFACE_RETURN_ERROR; 482 } 483 484 return EGONG_INTERFACE_RETURN_OK; 485 } 486 int EGong_if_win_display_window(struct EGong_interface *interface, const String *msg){ 487 /*if((unsigned int)EGong_if_win_messagegui_text.extra==1){ 488 EGong_if_win_messagegui_text.text=realloc(EGong_if_win_messagegui_text.text, msg->length+1*sizeof(wchar_t)); 489 } 490 else{ 491 EGong_if_win_messagegui_text.text=calloc(msg->length+1, sizeof(wchar_t)); 492 EGong_if_win_messagegui_text.extra=(void *)(unsigned int)1; 493 } 494 mbstowcs(EGong_if_win_messagegui_text.text, msg->data, msg->length+1); 495 EGong_if_win_create(NULL, &EGong_if_win_messagegui, 0); 496 EGong_if_win_show_element(&EGong_if_win_messagegui);*/ 497 wchar_t msgw[msg->length+1]; 498 mbstowcs(msgw, msg->data, msg->length); 499 msgw[msg->length]='\0'; 500 MessageBox(NULL, msgw, GUIT("EGong Nachricht"), MB_OK); 501 return EGONG_INTERFACE_RETURN_OK; 502 } 503 504 int EGong_if_win_display(struct EGong_interface *interface, const String *msg){ 505 if((EGong_global_configuration.gui.destinations&EGONG_CONFIG_GUI_DEST_NOTIFY)>0){ 506 EGong_if_win_display_notify(interface, msg); 507 } 508 if((EGong_global_configuration.gui.destinations&EGONG_CONFIG_GUI_DEST_WINDOW)>0){ 509 EGong_if_win_display_window(interface, msg); 510 } 511 return EGONG_INTERFACE_RETURN_OK; 512 } 513 514 void EGong_if_win_destroy(struct EGong_GUI_item *item){ 515 unsigned int i; 516 switch(item->type){ 517 case EGONG_GUI_WINDOW: 518 DestroyWindow(item->itemptr); 519 break; 520 case EGONG_GUI_LABEL: 521 if((unsigned int)item->extra==1){ 522 free(item->text); 523 } 524 break; 525 case EGONG_GUI_BUTTON: 526 break; 527 case EGONG_GUI_MENUITEM: 528 case EGONG_GUI_MENUITEM_IMAGE: 529 if(item->userdata!=NULL){ 530 DestroyMenu(item->userdata); 531 } 532 break; 533 case EGONG_GUI_MENUITEM_SEPARATOR: 534 break; 535 case EGONG_GUI_MENU: 536 DestroyMenu(item->itemptr); 537 break; 538 case EGONG_GUI_HBOX: 539 case EGONG_GUI_VBOX: 540 case EGONG_GUI_SYSTRAY: 541 free(item->userdata); 542 break; 543 } 544 545 546 if(item->child!=NULL){ 547 for(i=0; item->child[i]!=NULL; i++){ 548 EGong_if_win_destroy(item->child[i]); 549 } 550 } 551 } 552 int EGong_if_win_waiter_add(int sock, unsigned short int type){ 553 if(type==EGONG_WAITER_SOCKET){ 554 struct EGong_GUI_item *main=*(struct EGong_GUI_item **)Array_get(&EGong_if_win_windows,0); 555 WSAAsyncSelect(sock,(HWND)main->itemptr,WM_SOCKET,FD_ACCEPT|FD_READ); 556 } 557 else{ 558 do_log("Sorry, only sockets here...", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR); 559 return -1; 560 } 561 return 0; 562 } 563 void EGong_if_win_destroy_wrapper(struct EGong_GUI_item **item){ 564 EGong_if_win_destroy(*item); 565 } 566 int EGong_if_win_shutdown(struct EGong_interface *interface){ 567 Array_foreach(&EGong_if_win_windows, (void(*)(void*))&EGong_if_win_destroy_wrapper); 568 Array_destroy(&EGong_if_win_menus); 569 Array_destroy(&EGong_if_win_windows); 570 571 PostQuitMessage(0); 572 MSG msg; 573 while(GetMessage(&msg, NULL, 0, 0)!=0){ 574 TranslateMessage(&msg); 575 DispatchMessage(&msg); 576 } 577 return EGONG_INTERFACE_RETURN_EXIT; 578 } 579 int EGong_if_win_loop(void){ 580 int ret; 581 while(WaitMessage()){ 582 if((ret=EGong_interface_cycle())!=EGONG_INTERFACE_RETURN_OK){ 583 return ret; 584 } 585 } 586 }