3 Simple GUI abstraction- Windows implementation
\r
5 Part of the swftools package.
\r
7 Copyright (c) 2005 Matthias Kramm <kramm@quiss.org>
\r
9 This program is free software; you can redistribute it and/or modify
\r
10 it under the terms of the GNU General Public License as published by
\r
11 the Free Software Foundation; either version 2 of the License, or
\r
12 (at your option) any later version.
\r
14 This program is distributed in the hope that it will be useful,
\r
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
17 GNU General Public License for more details.
\r
19 You should have received a copy of the GNU General Public License
\r
20 along with this program; if not, write to the Free Software
\r
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
\r
23 #include <windows.h>
\r
24 #include <commctrl.h>
\r
29 static LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
\r
31 static char szWinName[] = "MyWin";
\r
34 static char*text="";
\r
38 static HDC dc, memDc;
\r
39 static HBITMAP piccy;
\r
41 static int sizex=640;
\r
42 static int sizey=388;
\r
43 static char *screen;
\r
44 static char *offscreen;
\r
45 static int screensize;
\r
47 static DWORD threadID;
\r
48 static DWORD mainthreadID;
\r
49 static HANDLE thread;
\r
50 static HINSTANCE me,prev;
\r
51 static int nWinMode;
\r
52 static int posx,posy;
\r
53 static RECT desktopSize;
\r
54 static int initialized = 0;
\r
56 static int cwidth=640,cheight=388;
\r
60 static void openWindow(int _sizex, int _sizey)
\r
67 ok = (int)GetClientRect(GetDesktopWindow(), &r);
\r
75 hwnd=CreateWindow(szWinName,
\r
77 WS_POPUP|WS_VISIBLE,
\r
78 posx=100, //CW_USEDEFAULT,
\r
79 posy=200, //CW_USEDEFAULT,
\r
83 SendMessage(hwnd, 1024+5 /*SB_SETBORDERS*/, 0, 0);
\r
85 ShowWindow(hwnd,nWinMode);
\r
89 memDc=CreateCompatibleDC(dc);
\r
90 // SetTimer(hwnd,1,1000,NULL);
\r
91 // SetTimer(hwnd,1,33,NULL);
\r
96 memset(&info, sizeof(info), 0);
\r
97 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
\r
98 info.bmiHeader.biWidth = sizex;
\r
99 info.bmiHeader.biHeight = sizey;
\r
100 info.bmiHeader.biPlanes= 1;
\r
101 info.bmiHeader.biBitCount = 24;
\r
102 info.bmiHeader.biCompression = BI_RGB;
\r
103 info.bmiHeader.biSizeImage = sizex*sizey*3;
\r
105 piccy = CreateDIBSection(0, &info, DIB_RGB_COLORS, &ppvBits, 0,0);
\r
106 screen = (char*)ppvBits;
\r
107 offscreen = (char*)malloc(sizex*sizey*4);
\r
108 screensize = sizex*sizey*3;
\r
111 screen = (char*)malloc(sizex*sizey*3);
\r
112 offscreen = (char*)malloc(sizex*sizey*4);
\r
113 screensize = sizex*sizey*3;
\r
114 piccy = CreateBitmap(sizex, sizey, 1, 24, screen);
\r
117 SelectObject(memDc,piccy);
\r
121 static void closeWindow()
\r
124 ReleaseDC(hwnd,dc);
\r
128 static int initwin32()
\r
134 me = GetModuleHandle(NULL);
\r
136 nWinMode = SW_SHOW;
\r
138 if(GetClassInfo(0, szWinName, &wcl)) {
\r
139 /* already registered */
\r
143 wcl.lpszClassName=szWinName;
\r
144 wcl.lpfnWndProc =WindowFunc;
\r
146 wcl.hIcon =LoadIcon (NULL, IDI_HAND);
\r
147 wcl.hCursor =LoadCursor(NULL, IDC_HAND);//IDC_CROSS);
\r
148 wcl.lpszMenuName =NULL;
\r
151 wcl.hbrBackground=(HBRUSH)GetStockObject(NULL_BRUSH);//WHITE_BRUSH);
\r
153 if(!RegisterClass(&wcl))
\r
156 //mainthreadID = GetCurrentThreadId();
\r
158 //openWindow(640,388);
\r
160 //thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(maincaller), (/*data*/0), 0, (LPDWORD)&(threadID));
\r
162 /*while(GetMessage(&msg,NULL,0,0))
\r
164 TranslateMessage(&msg);
\r
165 DispatchMessage(&msg);
\r
169 //ret = msg.wParam;
\r
176 #define Q_REDRAW 0x7f01
\r
177 #define Q_DUMMY 0x7f02
\r
179 static LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
\r
184 PostQuitMessage(0);
\r
187 BitBlt(dc,0,0,sizex,sizey,memDc,0,0,SRCCOPY);
\r
193 for(y=0;y<sizey;y++) {
\r
194 unsigned char*o = (unsigned char*)&offscreen[y*sizex*4];
\r
195 unsigned char*s = (unsigned char*)&screen[(sizey-y-1)*sizex*3];
\r
196 for(x=0;x<sizex;x++) {
\r
206 SetBitmapBits(piccy, screensize, screen);
\r
207 InvalidateRect(hwnd,NULL,1);
\r
211 //SetDIBitsToDevice
\r
212 BitBlt(dc,0,0,sizex,sizey,memDc,0,0,SRCCOPY);
\r
214 BitBlt(dc,0,0,sizex,sizey,memDc,0,0,SRCCOPY);
\r
219 //InvalidateRect(hwnd,NULL,1);
\r
221 return DefWindowProc(hwnd, message, wParam, lParam);
\r
226 static void ModeRGB_on(window_t*win)
\r
229 //printf("on()\n");
\r
230 openWindow(sizex, sizey);
\r
231 win->currentscr = (unsigned char*)offscreen;
\r
233 while(GetMessage(&msg,NULL,0,0))
\r
235 TranslateMessage(&msg);
\r
236 DispatchMessage(&msg);
\r
237 if(msg.message == WM_PAINT)
\r
241 static void ModeRGB_off(window_t*win)
\r
244 //printf("off()\n");
\r
245 //TODO: shouldn't this be DestroyWindow(hwnd)?
\r
246 PostMessage(hwnd, WM_DESTROY, 0, 0);
\r
247 while(GetMessage(&msg,NULL,0,0))
\r
249 TranslateMessage(&msg);
\r
250 DispatchMessage(&msg);
\r
251 if(msg.message == WM_DESTROY)
\r
255 win->currentscr = win->lastscr = 0;
\r
257 static void ModeRGB_flippage(window_t*win)
\r
260 PostMessage(hwnd, Q_REDRAW, 0, 0);
\r
261 while(GetMessage(&msg,NULL,0,0))
\r
263 TranslateMessage(&msg);
\r
264 DispatchMessage(&msg);
\r
265 if(msg.message == Q_REDRAW)
\r
268 win->currentscr = (byte*)offscreen;
\r
270 static gfxevent_t ModeRGB_getEvent(window_t*win)
\r
277 //PostMessage(hwnd, Q_DUMMY, 0, 0);
\r
279 event.type = GFXEVENT_NOTHING;
\r
286 if(!PeekMessage(&msg,NULL,0,0,0))
\r
287 return event;//nothing
\r
289 while(GetMessage(&msg,NULL,0,0))
\r
291 lParam = msg.lParam;
\r
292 wParam = msg.wParam;
\r
293 if(msg.message == Q_DUMMY) {
\r
294 event.type = GFXEVENT_NOTHING;
\r
296 } else if(msg.message == WM_LBUTTONDOWN) {
\r
297 event.type = GFXEVENT_MOUSEPRESS;
\r
299 event.x = (signed short int)LOWORD(lParam);
\r
300 event.y = (signed short int)HIWORD(lParam);
\r
303 } else if(msg.message == WM_LBUTTONUP) {
\r
304 event.type = GFXEVENT_MOUSERELEASE;
\r
306 event.x = (signed short int)LOWORD(lParam);
\r
307 event.y = (signed short int)HIWORD(lParam);
\r
310 } else if(msg.message == WM_MBUTTONDOWN) {
\r
311 event.type = GFXEVENT_MOUSEPRESS;
\r
313 event.x = (signed short int)LOWORD(lParam);
\r
314 event.y = (signed short int)HIWORD(lParam);
\r
317 } else if(msg.message == WM_MBUTTONUP) {
\r
318 event.type = GFXEVENT_MOUSERELEASE;
\r
320 event.x = (signed short int)LOWORD(lParam);
\r
321 event.y = (signed short int)HIWORD(lParam);
\r
324 } else if(msg.message == WM_RBUTTONDOWN) {
\r
325 event.type = GFXEVENT_MOUSEPRESS;
\r
327 event.x = (signed short int)LOWORD(lParam);
\r
328 event.y = (signed short int)HIWORD(lParam);
\r
331 } else if(msg.message == WM_RBUTTONUP) {
\r
332 event.type = GFXEVENT_MOUSERELEASE;
\r
334 event.x = (signed short int)LOWORD(lParam);
\r
335 event.y = (signed short int)HIWORD(lParam);
\r
338 } else if(msg.message == WM_MOUSEMOVE) {
\r
339 event.type = GFXEVENT_MOUSEMOVE;
\r
340 event.x = (signed short int)LOWORD(lParam);
\r
341 event.y = (signed short int)HIWORD(lParam);
\r
343 } else if(msg.message == WM_CHAR) {
\r
344 event.type = GFXEVENT_KEYPRESS;
\r
345 event.key = (char)wParam;
\r
348 TranslateMessage(&msg);
\r
349 DispatchMessage(&msg);
\r
350 event.type = GFXEVENT_NOTHING;
\r
356 static void ModeRGB_move(window_t*win, int relx,int rely)
\r
359 PostMessage(hwnd, Q_DUMMY, 0, 0);
\r
360 while(GetMessage(&msg,NULL,0,0))
\r
362 if(msg.message == WM_LBUTTONUP) {
\r
363 SendMessage(hwnd, msg.message, msg.wParam, msg.lParam);
\r
366 TranslateMessage(&msg);
\r
367 DispatchMessage(&msg);
\r
368 if(msg.message == Q_DUMMY)
\r
374 if(posx > desktopSize.right-cwidth) posx = desktopSize.right-cwidth;
\r
375 if(posy > desktopSize.bottom-cheight) posy = desktopSize.bottom-cheight;
\r
376 if(posx < desktopSize.left) posx = desktopSize.left;
\r
377 if(posy < desktopSize.top) posy = desktopSize.top;
\r
379 SetWindowPos(hwnd, HWND_TOP, posx, posy, 0, 0, SWP_NOSIZE);
\r
380 PostMessage(hwnd, Q_DUMMY, 0, 0);
\r
381 while(GetMessage(&msg,NULL,0,0))
\r
383 if(msg.message == WM_LBUTTONUP) {
\r
384 SendMessage(hwnd, msg.message, msg.wParam, msg.lParam);
\r
387 TranslateMessage(&msg);
\r
388 DispatchMessage(&msg);
\r
389 if(msg.message == Q_DUMMY)
\r
393 static void ModeRGB_resize(window_t*win, int width,int height)
\r
395 if(width>sizex || height>sizey) {
\r
396 printf("mode24::resize: can only make windows smaller\n");
\r
399 if(width<1) width=1;
\r
400 if(height<1) height=1;
\r
403 SetWindowPos(hwnd, HWND_TOP, 0, 0, width, height, SWP_NOMOVE);
\r
404 win->move(win,0,0);
\r
408 window_t* window_new(window_t*win, int width, int height)
\r
410 window_t*w = (window_t*)malloc(sizeof(window_t));
\r
411 memset(w, 0, sizeof(window_t));
\r
414 w->currentscr = w->lastscr = 0;
\r
419 //printf("contruct(%d, %d)\n", x, y);
\r
420 w->on = ModeRGB_on;
\r
421 w->off = ModeRGB_off;
\r
422 w->move = ModeRGB_move;
\r
423 w->resize = ModeRGB_resize;
\r
424 w->flippage = ModeRGB_flippage;
\r
425 w->getEvent = ModeRGB_getEvent;
\r
427 w->height = height;
\r