📄 fl_win32.cxx
字号:
Fl::flush(); // it never returns to main loop when deactivated... break; case WM_SHOWWINDOW: if (!window->parent()) Fl::handle(wParam ? FL_SHOW : FL_HIDE, window); break; case WM_KEYDOWN: case WM_SYSKEYDOWN: case WM_KEYUP: case WM_SYSKEYUP: // save the keysym until we figure out the characters: Fl::e_keysym = ms2fltk(wParam,lParam&(1<<24)); // See if TranslateMessage turned it into a WM_*CHAR message: if (PeekMessage(&fl_msg, hWnd, WM_CHAR, WM_SYSDEADCHAR, 1)) { uMsg = fl_msg.message; wParam = fl_msg.wParam; lParam = fl_msg.lParam; } case WM_DEADCHAR: case WM_SYSDEADCHAR: case WM_CHAR: case WM_SYSCHAR: {ulong state = Fl::e_state & 0xff000000; // keep the mouse button state // if GetKeyState is expensive we might want to comment some of these out: if (GetKeyState(VK_SHIFT)&~1) state |= FL_SHIFT; if (GetKeyState(VK_CAPITAL)) state |= FL_CAPS_LOCK; if (GetKeyState(VK_CONTROL)&~1) state |= FL_CTRL; // Alt gets reported for the Alt-GR switch on foreign keyboards. // so we need to check the event as well to get it right: if ((lParam&(1<<29)) //same as GetKeyState(VK_MENU) && uMsg != WM_CHAR) state |= FL_ALT; if (GetKeyState(VK_NUMLOCK)) state |= FL_NUM_LOCK; if (GetKeyState(VK_LWIN)&~1 || GetKeyState(VK_RWIN)&~1) { // WIN32 bug? GetKeyState returns garbage if the user hit the // meta key to pop up start menu. Sigh. if ((GetAsyncKeyState(VK_LWIN)|GetAsyncKeyState(VK_RWIN))&~1) state |= FL_META; } if (GetKeyState(VK_SCROLL)) state |= FL_SCROLL_LOCK; Fl::e_state = state;} if (lParam & (1<<31)) goto DEFAULT; // ignore up events after fixing shift if (uMsg == WM_CHAR || uMsg == WM_SYSCHAR) { buffer[0] = char(wParam); Fl::e_length = 1; } else if (Fl::e_keysym >= FL_KP && Fl::e_keysym <= FL_KP_Last) { buffer[0] = Fl::e_keysym-FL_KP; Fl::e_length = 1; } else { buffer[0] = 0; Fl::e_length = 0; } Fl::e_text = buffer; // for (int i = lParam&0xff; i--;) while (window->parent()) window = window->window(); if (Fl::handle(FL_KEYBOARD,window)) return 0; break; case WM_GETMINMAXINFO: Fl_X::i(window)->set_minmax((LPMINMAXINFO)lParam); break; case WM_SIZE: if (!window->parent()) { if (wParam == SIZE_MINIMIZED || wParam == SIZE_MAXHIDE) { Fl::handle(FL_HIDE, window); } else { Fl::handle(FL_SHOW, window); resize_bug_fix = window; window->size(LOWORD(lParam), HIWORD(lParam)); } } break; case WM_MOVE: resize_bug_fix = window; window->position(LOWORD(lParam), HIWORD(lParam)); break; case WM_SETCURSOR: if (LOWORD(lParam) == HTCLIENT) { while (window->parent()) window = window->window(); SetCursor(Fl_X::i(window)->cursor); return 0; } break;#if USE_COLORMAP case WM_QUERYNEWPALETTE : fl_GetDC(hWnd); if (fl_select_palette()) InvalidateRect(hWnd, NULL, FALSE); break; case WM_PALETTECHANGED: fl_GetDC(hWnd); if ((HWND)wParam != hWnd && fl_select_palette()) UpdateColors(fl_gc); break; case WM_CREATE : fl_GetDC(hWnd); fl_select_palette(); break;#endif default: DEFAULT: if (Fl::handle(0,0)) return 0; break; } return DefWindowProc(hWnd, uMsg, wParam, lParam);}////////////////////////////////////////////////////////////////// This function gets the dimensions of the top/left borders and// the title bar, if there is one, based on the FL_BORDER, FL_MODAL// and FL_NONMODAL flags, and on the window's size range.// It returns the following values://// value | border | title bar// 0 | none | no// 1 | fix | yes// 2 | size | yesint Fl_X::fake_X_wm(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by) { int W, H, xoff, yoff, dx, dy; int ret = bx = by = bt = 0; if (w->border() && !w->parent()) { if (w->maxw != w->minw || w->maxh != w->minh) { ret = 2; bx = GetSystemMetrics(SM_CXSIZEFRAME); by = GetSystemMetrics(SM_CYSIZEFRAME); } else { ret = 1; bx = GetSystemMetrics(SM_CXFIXEDFRAME); by = GetSystemMetrics(SM_CYFIXEDFRAME); } bt = GetSystemMetrics(SM_CYCAPTION); } //The coordinates of the whole window, including non-client area xoff = bx; yoff = by + bt; dx = 2*bx; dy = 2*by + bt; X = w->x()-xoff; Y = w->y()-yoff; W = w->w()+dx; H = w->h()+dy; //Proceed to positioning the window fully inside the screen, if possible //Make border's lower right corner visible if (Fl::w() < X+W) X = Fl::w() - W; if (Fl::h() < Y+H) Y = Fl::h() - H; //Make border's upper left corner visible if (X<0) X = 0; if (Y<0) Y = 0; //Make client area's lower right corner visible if (Fl::w() < X+dx+ w->w()) X = Fl::w() - w->w() - dx; if (Fl::h() < Y+dy+ w->h()) Y = Fl::h() - w->h() - dy; //Make client area's upper left corner visible if (X+xoff < 0) X = -xoff; if (Y+yoff < 0) Y = -yoff; //Return the client area's top left corner in (X,Y) X+=xoff; Y+=yoff; return ret;}////////////////////////////////////////////////////////////////void Fl_Window::resize(int X,int Y,int W,int H) { UINT flags = SWP_NOSENDCHANGING | SWP_NOZORDER; int is_a_resize = (W != w() || H != h()); int resize_from_program = (this != resize_bug_fix); if (!resize_from_program) resize_bug_fix = 0; if (X != x() || Y != y()) set_flag(FL_FORCE_POSITION); else {if (!is_a_resize) return; flags |= SWP_NOMOVE;} if (is_a_resize) { Fl_Group::resize(X,Y,W,H); if (shown()) {redraw(); i->wait_for_expose = 1;} } else { x(X); y(Y); flags |= SWP_NOSIZE; } if (resize_from_program && shown()) { int dummy, bt, bx, by; //Ignore window managing when resizing, so that windows (and more //specifically menus) can be moved offscreen. if (Fl_X::fake_X_wm(this, dummy, dummy, bt, bx, by)) { X -= bx; Y -= by+bt; W += 2*bx; H += 2*by+bt; } SetWindowPos(i->xid, 0, X, Y, W, H, flags); }}////////////////////////////////////////////////////////////////void fl_fix_focus(); // in Fl.Cchar fl_show_iconic; // hack for Fl_Window::iconic()// int fl_background_pixel = -1; // color to use for backgroundHCURSOR fl_default_cursor;int fl_disable_transient_for; // secret method of removing TRANSIENT_FORFl_X* Fl_X::make(Fl_Window* w) { Fl_Group::current(0); // get rid of very common user bug: forgot end() const char* class_name = /*w->xclass(); if (!class_name) class_name =*/ "FLTK"; // create a "FLTK" WNDCLASS WNDCLASSEX wc; // Documentation states a device context consumes about 800 bytes // of memory... so who cares? If 800 bytes per window is what it // takes to speed things up, I'm game. //wc.style = CS_HREDRAW | CS_VREDRAW | CS_CLASSDC | CS_DBLCLKS; wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS; wc.lpfnWndProc = (WNDPROC)WndProc; wc.cbClsExtra = wc.cbWndExtra = 0; wc.hInstance = fl_display; if (!w->icon()) w->icon((void *)LoadIcon(NULL, IDI_APPLICATION)); wc.hIcon = wc.hIconSm = (HICON)w->icon(); wc.hCursor = fl_default_cursor = LoadCursor(NULL, IDC_ARROW); //uchar r,g,b; Fl::get_color(FL_GRAY,r,g,b); //wc.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(r,g,b)); wc.hbrBackground = NULL; wc.lpszMenuName = NULL; wc.lpszClassName = class_name; wc.cbSize = sizeof(WNDCLASSEX); RegisterClassEx(&wc); HWND parent; DWORD style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS; DWORD styleEx = WS_EX_LEFT; int xp = w->x(); int yp = w->y(); int wp = w->w(); int hp = w->h(); if (w->parent()) { style = WS_CHILD; styleEx = WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT; parent = fl_xid(w->window()); } else { if (!w->size_range_set) { if (w->resizable()) { Fl_Widget *o = w->resizable(); int minw = o->w(); if (minw > 100) minw = 100; int minh = o->h(); if (minh > 100) minh = 100; w->size_range(w->w() - o->w() + minw, w->h() - o->h() + minh, 0, 0); } else { w->size_range(w->w(), w->h(), w->w(), w->h()); } } styleEx |= WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT; int xwm = xp , ywm = yp , bt, bx, by; switch (fake_X_wm(w, xwm, ywm, bt, bx, by)) { // No border (user for menus) case 0: style |= WS_POPUP; break; // Thin border and title bar case 1: style |= WS_DLGFRAME | WS_CAPTION; break; // Thick, resizable border and title bar, with maximize button case 2: style |= WS_THICKFRAME | WS_MAXIMIZEBOX | WS_CAPTION ; break; } if (by+bt) { if (!w->non_modal()) style |= WS_SYSMENU | WS_MINIMIZEBOX; wp += 2*bx; hp += 2*by+bt; } if (!(w->flags() & Fl_Window::FL_FORCE_POSITION)) { xp = yp = CW_USEDEFAULT; } else { if (!Fl::grab()) { xp = xwm; yp = ywm; w->x(xp);w->y(yp); } xp -= bx; yp -= by+bt; } parent = 0; if (w->non_modal() && Fl_X::first && !fl_disable_transient_for) { // find some other window to be "transient for": Fl_Window* w = Fl_X::first->w; while (w->parent()) w = w->window(); parent = fl_xid(w); } } Fl_X* x = new Fl_X; x->other_xid = 0; x->setwindow(w); x->region = 0; x->private_dc = 0; x->cursor = fl_default_cursor; x->xid = CreateWindowEx( styleEx, class_name, w->label(), style, xp, yp, wp, hp, parent, NULL, // menu fl_display, NULL // creation parameters ); x->next = Fl_X::first; Fl_X::first = x; x->wait_for_expose = 1; w->set_visible(); w->handle(FL_SHOW); // get child windows to appear w->redraw(); // force draw to happen // If we've captured the mouse, we dont want do activate any // other windows from the code, or we loose the capture. ShowWindow(x->xid, fl_show_iconic ? SW_SHOWMINNOACTIVE : fl_capture? SW_SHOWNOACTIVATE : SW_SHOWNORMAL); fl_show_iconic = 0; if (w->modal()) {Fl::modal_ = w; fl_fix_focus();} return x;}////////////////////////////////////////////////////////////////HINSTANCE fl_display = GetModuleHandle(NULL);void Fl_Window::size_range_() { size_range_set = 1;}void Fl_X::set_minmax(LPMINMAXINFO minmax){ int td, wd, hd, dummy; fake_X_wm(w, dummy, dummy, td, wd, hd); wd *= 2; hd *= 2; hd += td; minmax->ptMinTrackSize.x = w->minw + wd; minmax->ptMinTrackSize.y = w->minh + hd; if (w->maxw) { minmax->ptMaxTrackSize.x = w->maxw + wd; minmax->ptMaxSize.x = w->maxw + wd; } if (w->maxh) { minmax->ptMaxTrackSize.y = w->maxh + hd; minmax->ptMaxSize.y = w->maxh + hd; }}////////////////////////////////////////////////////////////////#include <FL/filename.H> // need so FL_EXPORT filename_name works// returns pointer to the filename, or null if name ends with '/'const char *filename_name(const char *name) { const char *p,*q; q = name; if (q[0] && q[1]==':') q += 2; // skip leading drive letter for (p = q; *p; p++) if (*p == '/' || *p == '\\') q = p+1; return q;}void Fl_Window::label(const char *name,const char *iname) { Fl_Widget::label(name); iconlabel_ = iname; if (shown() && !parent()) { if (!name) name = ""; SetWindowText(i->xid, name); // if (!iname) iname = filename_name(name); // should do something with iname here... }}////////////////////////////////////////////////////////////////// Implement the virtual functions for the base Fl_Window class:// If the box is a filled rectangle, we can make the redisplay *look*// faster by using X's background pixel erasing. We can make it// actually *be* faster by drawing the frame only, this is done by// setting fl_boxcheat, which is seen by code in fl_drawbox.C:// For WIN32 it looks like all windows share a background color, so// I use FL_GRAY for this and only do this cheat for windows that are// that color.// Actually it is totally disabled.// Fl_Widget *fl_boxcheat;//static inline int can_boxcheat(uchar b) {return (b==1 || (b&2) && b<=15);}void Fl_Window::show() { if (!shown()) { // if (can_boxcheat(box())) fl_background_pixel = fl_xpixel(color()); Fl_X::make(this); } else { // Once again, we would lose the capture if we activated the window. if (IsIconic(i->xid)) OpenIcon(i->xid); if (!fl_capture) BringWindowToTop(i->xid); //ShowWindow(i->xid,fl_capture?SW_SHOWNOACTIVATE:SW_RESTORE); }}Fl_Window *Fl_Window::current_;// the current contextHDC fl_gc = 0;// the current window handle, initially set to -1 so we can correctly// allocate fl_GetDC(0)HWND fl_window = (HWND)-1;// Here we ensure only one GetDC is ever in place.HDC fl_GetDC(HWND w) { if (fl_gc) { if (w == fl_window) return fl_gc; ReleaseDC(fl_window, fl_gc); } fl_gc = GetDC(w); fl_window = w; // calling GetDC seems to always reset these: (?) SetTextAlign(fl_gc, TA_BASELINE|TA_LEFT); SetBkMode(fl_gc, TRANSPARENT); return fl_gc;}// make X drawing go into this window (called by subclass flush() impl.)void Fl_Window::make_current() { fl_GetDC(fl_xid(this));#if USE_COLORMAP // Windows maintains a hardware and software color palette; the // SelectPalette() call updates the current soft->hard mapping // for all drawing calls, so we must select it here before any // code does any drawing... fl_select_palette();#endif // USE_COLORMAP current_ = this; fl_clip_region(0);}//// End of "$Id: Fl_win32.cxx,v 1.1.1.1 2003/08/07 21:18:40 jasonk Exp $".//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -