00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <assert.h>
00032 #include <windows.h>
00033 #include <richedit.h>
00034
00035 #include "gui.h"
00036 #include "main.h"
00037 #include "error_management.h"
00038
00039 BOOL gui_paint(s_gui_tab_layout *_gui_layout, HDC hdc);
00040 int gui_get_item_w_coord(s_gui_tab_layout *_gui_layout, int *x, int *y);
00041 s_gui_tab_layout_item *gui_is_hwnd(s_gui_tab_layout *_gui_layout, HWND hwnd);
00042 void get_path(char *_path, int size);
00043
00044 void get_path(char *_path, int size)
00045 {
00046 char *_c;
00047
00048 _c = _path + GetModuleFileName(NULL, _path, size);
00049 while(*_c != '\\' && _c > _path)
00050 _c--;
00051 if (_c == _path)
00052 SET_ERROR("Unable to find module path.");
00053
00054 _c[1] = '\0';
00055 }
00056
00057 void gui_set_font(s_gui_tab_layout_item *_gui_item, char *_name, int height, BOOL bolt, BOOL italic, BOOL underlined)
00058 {
00059 HFONT hfont, hfont_old;
00060 LOGFONT lf;
00061
00062 ASSERT(_gui_item);
00063
00064 memset(&lf, 0, sizeof(LOGFONT));
00065 strcpy(lf.lfFaceName, _name);
00066 lf.lfHeight = height;
00067 if (bolt)
00068 lf.lfWeight = FW_BLACK;
00069 lf.lfItalic = italic;
00070 lf.lfUnderline = underlined;
00071
00072 hfont_old = (HFONT) SendMessage(_gui_item->hwnd, WM_GETFONT, 0, 0);
00073 hfont = CreateFontIndirect(&lf);
00074 SendMessage(_gui_item->hwnd, WM_SETFONT, (WPARAM) hfont, MAKELPARAM(TRUE, 0));
00075 if (hfont_old)
00076 DeleteObject(hfont_old);
00077 }
00078
00079
00080 void gui_rescale(s_gui_tab_layout *_gui_layout, float scale_x, float scale_y, BOOL repaint)
00081 {
00082 int i, offset_x, offset_y;
00083 s_gui_tab_layout_item *_gui_item;
00084 HFONT hfont, hfont_old;
00085 LOGFONT lf;
00086 int flags;
00087
00088 ASSERT(_gui_layout);
00089
00090 memset(&lf, 0, sizeof(LOGFONT));
00091 strcpy(lf.lfFaceName, "Arial");
00092
00093 if (repaint)
00094 flags = 0;
00095 else
00096 flags = SWP_NOREDRAW;
00097
00098 if (scale_x < 0 || scale_y < 0)
00099 flags |= SWP_NOMOVE | SWP_NOSIZE;
00100
00101 _gui_layout->scale_x = scale_x;
00102 _gui_layout->scale_y = scale_y;
00103
00104 for(i=0; i<_gui_layout->nb_elements; i++)
00105 {
00106 _gui_item = &_gui_layout->_gui_item[i];
00107 ASSERT(_gui_item);
00108 offset_x = 0;
00109 offset_y = 0;
00110
00111 if (_gui_item->type == GUI_TYPE_COMBOBOX)
00112 offset_y = (20*(scale_y-1))/2;
00113
00114 SetWindowPos(
00115 _gui_item->hwnd,
00116 NULL,
00117 _gui_item->x*scale_x+offset_x,
00118 _gui_item->y*scale_y+offset_y,
00119 _gui_item->width*scale_x,
00120 _gui_item->height*scale_y,
00121 flags | SWP_NOZORDER);
00122
00123 if (_gui_item->type != GUI_TYPE_COMBOBOX && !(_gui_item->style & ES_MULTILINE))
00124 {
00125 lf.lfHeight = _gui_item->height*scale_y-2;
00126 lf.lfWeight = 800;
00127 hfont_old = (HFONT) SendDlgItemMessage(_gui_layout->hwnd, _gui_item->id, WM_GETFONT, 0, 0);
00128 hfont = CreateFontIndirect(&lf);
00129 SendDlgItemMessage(_gui_layout->hwnd, _gui_item->id, WM_SETFONT, (WPARAM) hfont, MAKELPARAM(TRUE, 0));
00130 if (hfont_old)
00131 DeleteObject(hfont_old);
00132 }
00133 }
00134 }
00135
00136 void gui_new_tab_layout(s_gui_tab_layout *_gui_layout, int max_elements)
00137 {
00138 int i;
00139
00140 ASSERT(_gui_layout);
00141
00142 _gui_layout->_gui_item = (s_gui_tab_layout_item *) malloc(sizeof(s_gui_tab_layout_item)*max_elements);
00143 assert(_gui_layout->_gui_item);
00144 memset(_gui_layout->_gui_item, 0, sizeof(s_gui_tab_layout_item)*max_elements);
00145 _gui_layout->hwnd = NULL;
00146 _gui_layout->nb_elements = 0;
00147 for(i=0; i<max_elements; i++)
00148 _gui_layout->_gui_item[i].actif = FALSE;
00149 }
00150
00151 void gui_delete_tab_layout(s_gui_tab_layout *_gui_layout)
00152 {
00153 int i;
00154
00155 ASSERT(_gui_layout);
00156
00157 for(i=0; i<_gui_layout->nb_elements; i++)
00158 DestroyWindow(_gui_layout->_gui_item[i].hwnd);
00159 free(_gui_layout->_gui_item);
00160 }
00161
00162 void gui_create(s_gui_tab_layout *_gui_layout, HWND hwnd)
00163 {
00164 int i;
00165 static int id = 1;
00166 s_gui_tab_layout_item *_gui_item;
00167 HANDLE handle;
00168 char _path[MAX_PATH];
00169
00170 ASSERT(_gui_layout);
00171
00172 _gui_layout->hwnd = hwnd;
00173 _gui_layout->scale_x = 1.0;
00174 _gui_layout->scale_y = 1.0;
00175 for(i=0; i<_gui_layout->nb_elements; i++)
00176 {
00177 _gui_item = &_gui_layout->_gui_item[i];
00178 switch(_gui_item->type)
00179 {
00180 case GUI_TYPE_IMAGE:
00181 _gui_item->style |= WS_CHILD | WS_VISIBLE | SS_BITMAP;
00182 _gui_item->hwnd = CreateWindowEx(
00183 SS_BITMAP,
00184 "STATIC",
00185 _gui_item->_str,
00186 _gui_item->style,
00187 _gui_item->x,
00188 _gui_item->y,
00189 _gui_item->width,
00190 _gui_item->height,
00191 hwnd,
00192 (HMENU) id++,
00193 (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE),
00194 NULL);
00195 ASSERT(_gui_item->hwnd);
00196 _gui_item->id = GetDlgCtrlID(_gui_item->hwnd);
00197 get_path(_path, MAX_PATH);
00198 strcat(_path, "images\\");
00199 strcat(_path, _gui_item->_str);
00200 handle = (HANDLE) LoadImage(NULL,
00201 _path,
00202 IMAGE_BITMAP,
00203 0,
00204 0,
00205 LR_LOADFROMFILE | LR_DEFAULTSIZE);
00206 ASSERT(handle);
00207 SendMessage(_gui_item->hwnd, STM_SETIMAGE, (WPARAM) IMAGE_BITMAP, (LPARAM) handle);
00208 break;
00209 case GUI_TYPE_BUTTON:
00210 _gui_item->style |= WS_BORDER | WS_CHILD | WS_VISIBLE | WS_TABSTOP;
00211 _gui_item->hwnd = CreateWindowEx(
00212 0,
00213 "BUTTON",
00214 _gui_item->_str,
00215 _gui_item->style,
00216 _gui_item->x,
00217 _gui_item->y,
00218 _gui_item->width,
00219 _gui_item->height,
00220 hwnd,
00221 (HMENU) id++,
00222 (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE),
00223 NULL);
00224 ASSERT(_gui_item->hwnd);
00225 _gui_item->id = GetDlgCtrlID(_gui_item->hwnd);
00226 break;
00227 case GUI_TYPE_PAINT:
00228 break;
00229 case GUI_TYPE_STATIC:
00230 _gui_item->style |= WS_CHILD | WS_VISIBLE;
00231 _gui_item->hwnd = CreateWindowEx(
00232 0,
00233 "STATIC",
00234 _gui_item->_str,
00235 _gui_item->style,
00236 _gui_item->x,
00237 _gui_item->y,
00238 _gui_item->width,
00239 _gui_item->height,
00240 hwnd,
00241 (HMENU) id++,
00242 (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE),
00243 NULL);
00244 ASSERT(_gui_item->hwnd);
00245 _gui_item->id = GetDlgCtrlID(_gui_item->hwnd);
00246 break;
00247 case GUI_TYPE_EDIT:
00248 _gui_item->style |= WS_CHILD | WS_VISIBLE | WS_TABSTOP;
00249 _gui_item->hwnd = CreateWindowEx(
00250 0,
00251 "EDIT",
00252 _gui_item->_str,
00253 _gui_item->style | ES_MULTILINE,
00254 _gui_item->x,
00255 _gui_item->y,
00256 _gui_item->width,
00257 _gui_item->height,
00258 hwnd,
00259 (HMENU) id++,
00260 (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE),
00261 NULL);
00262 ASSERT(_gui_item->hwnd);
00263 _gui_item->id = GetDlgCtrlID(_gui_item->hwnd);
00264 break;
00265 case GUI_TYPE_COMBOBOX:
00266 _gui_item->style |= WS_VSCROLL | WS_CHILD | WS_TABSTOP | WS_VISIBLE | CBS_SORT | CBS_DROPDOWN;
00267 _gui_item->hwnd = CreateWindowEx(
00268 0,
00269 "COMBOBOX",
00270 _gui_item->_str,
00271 _gui_item->style,
00272 _gui_item->x,
00273 _gui_item->y,
00274 _gui_item->width,
00275 _gui_item->height,
00276 hwnd,
00277 (HMENU) id++,
00278 (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE),
00279 NULL);
00280 ASSERT(_gui_item->hwnd);
00281 _gui_item->id = GetDlgCtrlID(_gui_item->hwnd);
00282 break;
00283 case GUI_TYPE_RICHEDIT:
00284 _gui_item->style |= WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_BORDER | ES_MULTILINE | WS_HSCROLL | ES_AUTOVSCROLL | ES_NOHIDESEL;
00285 ASSERT(LoadLibrary("RICHED32.DLL"));
00286 _gui_item->hwnd = CreateWindowEx(
00287 WS_EX_CLIENTEDGE,
00288 RICHEDIT_CLASS,
00289 _gui_item->_str,
00290 _gui_item->style,
00291 _gui_item->x,
00292 _gui_item->y,
00293 _gui_item->width,
00294 _gui_item->height,
00295 hwnd,
00296 (HMENU) id++,
00297 (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE),
00298 NULL);
00299 ASSERT(_gui_item->hwnd);
00300 _gui_item->id = GetDlgCtrlID(_gui_item->hwnd);
00301 break;
00302 }
00303 _gui_item->actif = TRUE;
00304 }
00305 }
00306
00307 void gui_move(s_gui_tab_layout *_gui_layout, int x, int y)
00308 {
00309 int i, inf_x, inf_y;
00310 int dx, dy;
00311 s_gui_tab_layout_item *_gui_item;
00312
00313 ASSERT(_gui_layout);
00314
00315 inf_x = 0xFFFFFF;
00316 inf_y = 0xFFFFFF;
00317 for(i=0; i<_gui_layout->nb_elements; i++)
00318 {
00319 _gui_item = &_gui_layout->_gui_item[i];
00320 inf_x = (inf_x < _gui_item->x)?inf_x:_gui_item->x;
00321 inf_y = (inf_y < _gui_item->y)?inf_y:_gui_item->y;
00322 }
00323
00324 for(i=0; i<_gui_layout->nb_elements; i++)
00325 {
00326 _gui_item = &_gui_layout->_gui_item[i];
00327 _gui_item->x = _gui_item->x-inf_x + x;
00328 _gui_item->y = _gui_item->y-inf_y + y;
00329 SetWindowPos(
00330 _gui_item->hwnd,
00331 NULL,
00332 _gui_item->x,
00333 _gui_item->y,
00334 0,
00335 0,
00336 SWP_NOZORDER | SWP_NOSIZE);
00337 }
00338 }
00339
00340 void gui_visibility(s_gui_tab_layout *_gui_layout, BOOL visible)
00341 {
00342 int i;
00343 UINT uFlags;
00344
00345 ASSERT(_gui_layout);
00346
00347 uFlags = SWP_NOMOVE | SWP_NOZORDER | SWP_NOSIZE;
00348 if (visible)
00349 uFlags |= SWP_SHOWWINDOW;
00350 else
00351 uFlags |= SWP_HIDEWINDOW;
00352
00353 for(i=0; i<_gui_layout->nb_elements; i++)
00354 {
00355 if (visible)
00356 _gui_layout->_gui_item[i].actif = TRUE;
00357 else
00358 _gui_layout->_gui_item[i].actif = FALSE;
00359 SetWindowPos(_gui_layout->_gui_item[i].hwnd, NULL, 0, 0, 0, 0, uFlags);
00360 }
00361 }
00362
00363 void gui_visibility_item(s_gui_tab_layout_item *_gui_item, BOOL visible)
00364 {
00365 UINT uFlags;
00366
00367 ASSERT(_gui_item);
00368
00369 uFlags = SWP_NOMOVE | SWP_NOZORDER | SWP_NOSIZE;
00370 if (visible)
00371 uFlags |= SWP_SHOWWINDOW;
00372 else
00373 uFlags |= SWP_HIDEWINDOW;
00374
00375 if (visible)
00376 _gui_item->actif = TRUE;
00377 else
00378 _gui_item->actif = FALSE;
00379 SetWindowPos(_gui_item->hwnd, NULL, 0, 0, 0, 0, uFlags);
00380 }
00381
00382 int gui_get_item_w_coord(s_gui_tab_layout *_gui_layout, int *x, int *y)
00383 {
00384 int i;
00385 int new_x, new_y;
00386 s_gui_tab_layout_item *_gui_item;
00387
00388 ASSERT(_gui_layout);
00389
00390 for(i=0; i<_gui_layout->nb_elements; i++)
00391 {
00392 _gui_item = &_gui_layout->_gui_item[i];
00393 ASSERT(_gui_item);
00394 new_x = *x - _gui_item->x;
00395 new_y = *y - _gui_item->y;
00396 if (new_x < 0 || new_y < 0)
00397 continue;
00398 if (new_x < _gui_item->width && new_y < _gui_item->height)
00399 {
00400 *x = new_x;
00401 *y = new_y;
00402 return i;
00403 }
00404 }
00405
00406 return -1;
00407 }
00408
00409 s_gui_tab_layout_item *gui_is_hwnd(s_gui_tab_layout *_gui_layout, HWND hwnd)
00410 {
00411 int i;
00412
00413 ASSERT(_gui_layout);
00414
00415 for(i=0; i<_gui_layout->nb_elements; i++)
00416 if (_gui_layout->_gui_item[i].hwnd == hwnd)
00417 return &_gui_layout->_gui_item[i];
00418
00419 return NULL;
00420 }
00421
00422 LRESULT CALLBACK gui_proc(s_gui_tab_layout *_gui_layout, HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
00423 {
00424 static HBRUSH hbrush = NULL;
00425 LRESULT result;
00426 HDC hdc;
00427 PAINTSTRUCT ps;
00428 int item_id, msg_code;
00429 int i, x, y;
00430 s_gui_tab_layout_item *_gui_item;
00431 COLORREF bg_color, fg_color;
00432 char _temp[256];
00433
00434 result = 0;
00435 switch(message)
00436 {
00437 case WM_DESTROY:
00438 ASSERT(_gui_layout);
00439 gui_delete_tab_layout(_gui_layout);
00440 result = 1;
00441 break;
00442 case WM_PAINT:
00443 ASSERT(_gui_layout);
00444 hdc = BeginPaint(hwnd, &ps);
00445 result = gui_paint(_gui_layout, hdc);
00446 EndPaint(hwnd, &ps);
00447 break;
00448 case WM_MOUSEMOVE:
00449 case WM_LBUTTONDOWN:
00450 case WM_LBUTTONUP:
00451 case WM_LBUTTONDBLCLK:
00452 case WM_RBUTTONDOWN:
00453 case WM_RBUTTONUP:
00454 case WM_RBUTTONDBLCLK:
00455 ASSERT(_gui_layout);
00456 x = LOWORD(lParam);
00457 y = HIWORD(lParam);
00458 i = gui_get_item_w_coord(_gui_layout, &x, &y);
00459 if (i == -1)
00460 return 0;
00461 ASSERT(i >= 0 && i < _gui_layout->nb_elements);
00462 _gui_item = &_gui_layout->_gui_item[i];
00463 ASSERT(_gui_item);
00464 lParam = x + (y << 16);
00465 if (_gui_item->_f_proc)
00466 result = _gui_item->_f_proc(_gui_item->hwnd, message, wParam, lParam);
00467 break;
00468 case WM_CTLCOLORSTATIC:
00469 case WM_CTLCOLOREDIT:
00470 case WM_CTLCOLORSCROLLBAR:
00471 case WM_CTLCOLORLISTBOX:
00472 case WM_CTLCOLORBTN:
00473 ASSERT(_gui_layout);
00474 if (!(_gui_item = gui_is_hwnd(_gui_layout, (HWND) lParam)))
00475 break;
00476 hdc = (HDC) wParam;
00477 ASSERT(hdc);
00478 switch(_gui_item->type)
00479 {
00480 case GUI_TYPE_STATIC:
00481 bg_color = (_gui_item->background_color)?_gui_item->background_color:GUI_BACKGROUND_COLOR_STATIC;
00482 fg_color = (_gui_item->foreground_color)?_gui_item->foreground_color:GUI_FOREGROUND_COLOR_STATIC;
00483 break;
00484 case GUI_TYPE_RICHEDIT:
00485 case GUI_TYPE_EDIT:
00486 bg_color = (_gui_item->background_color)?_gui_item->background_color:GUI_BACKGROUND_COLOR_EDIT;
00487 fg_color = (_gui_item->foreground_color)?_gui_item->foreground_color:GUI_FOREGROUND_COLOR_EDIT;
00488 break;
00489 case GUI_TYPE_COMBOBOX:
00490 bg_color = (_gui_item->background_color)?_gui_item->background_color:GUI_BACKGROUND_COLOR_COMBOBOX;
00491 fg_color = (_gui_item->foreground_color)?_gui_item->foreground_color:GUI_FOREGROUND_COLOR_COMBOBOX;
00492 break;
00493 }
00494
00495 SetBkColor(hdc, bg_color);
00496 SetTextColor(hdc, fg_color);
00497 if (hbrush)
00498 DeleteObject(hbrush);
00499 hbrush = CreateSolidBrush(bg_color);
00500 ASSERT(hbrush);
00501 SelectObject(hdc, hbrush);
00502 result = (LRESULT) hbrush;
00503 break;
00504 case WM_COMMAND:
00505 ASSERT(_gui_layout);
00506 msg_code = (wParam >> 16) & 0xFFFF;
00507 item_id = wParam & 0xFFFF;
00508
00509 i = _gui_layout->nb_elements;
00510 _gui_item = NULL;
00511 while(i--)
00512 {
00513 _gui_item = &_gui_layout->_gui_item[i];
00514 ASSERT(_gui_item);
00515 if (_gui_item->id == item_id)
00516 break;
00517 }
00518 if (!_gui_item)
00519 {
00520 result = (LRESULT) 0;
00521 break;
00522 }
00523
00524 if (_gui_item->id == item_id)
00525 {
00526 if (_gui_item->_f_proc)
00527 result = _gui_item->_f_proc(_gui_item->hwnd, msg_code, wParam, lParam);
00528 else
00529 result = (LRESULT) 0;
00530 }
00531 else
00532 result = (LRESULT) 0;
00533 break;
00534 default:
00535 result = (LRESULT) 0;
00536 }
00537
00538 return result;
00539 }
00540
00541 BOOL gui_paint(s_gui_tab_layout *_gui_layout, HDC hdc)
00542 {
00543 HDC hdc_buffer;
00544 HBITMAP hbmp;
00545 int w, h;
00546 int i;
00547 RECT rect;
00548 s_gui_tab_layout_item *_gui_item;
00549
00550 GetUpdateRect(_gui_layout->hwnd, &rect, FALSE);
00551 for(i=0; i<_gui_layout->nb_elements; i++)
00552 {
00553 _gui_item = &_gui_layout->_gui_item[i];
00554 if (_gui_item->type == GUI_TYPE_PAINT)
00555 {
00556 w = _gui_item->width;
00557 h = _gui_item->height;
00558
00559 hbmp = CreateCompatibleBitmap(hdc, w, h);
00560 hdc_buffer = CreateCompatibleDC(hdc);
00561 SelectObject(hdc_buffer, hbmp);
00562
00563 _gui_item->_f_proc(_gui_item->hwnd, WM_PAINT, (WPARAM) hdc_buffer, (LPARAM) 0);
00564
00565 StretchBlt(hdc,
00566 _gui_item->x*_gui_layout->scale_x,
00567 _gui_item->y*_gui_layout->scale_y,
00568 w*_gui_layout->scale_x,
00569 h*_gui_layout->scale_y,
00570 hdc_buffer,
00571 0,
00572 0,
00573 w,
00574 h,
00575 SRCCOPY);
00576 DeleteObject(hbmp);
00577 DeleteDC(hdc_buffer);
00578 }
00579 }
00580 }