📄 tkwinx.c
字号:
/* *---------------------------------------------------------------------- * * Tk_TranslateWinEvent -- * * This function is called by widget window procedures to handle * the translation from Win32 events to Tk events. * * Results: * Returns 1 if the event was handled, else 0. * * Side effects: * Depends on the event. * *---------------------------------------------------------------------- */intTk_TranslateWinEvent(hwnd, message, wParam, lParam, resultPtr) HWND hwnd; UINT message; WPARAM wParam; LPARAM lParam; LRESULT *resultPtr;{ *resultPtr = 0; switch (message) { case WM_RENDERFORMAT: { TkWindow *winPtr = (TkWindow *) Tk_HWNDToWindow(hwnd); if (winPtr) { TkWinClipboardRender(winPtr->dispPtr, wParam); } return 1; } case WM_COMMAND: case WM_NOTIFY: case WM_VSCROLL: case WM_HSCROLL: { /* * Reflect these messages back to the sender so that they * can be handled by the window proc for the control. Note * that we need to be careful not to reflect a message that * is targeted to this window, or we will loop. */ HWND target = (message == WM_NOTIFY) ? ((NMHDR*)lParam)->hwndFrom : (HWND) lParam; if (target && target != hwnd) { *resultPtr = SendMessage(target, message, wParam, lParam); return 1; } break; } case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: case WM_LBUTTONUP: case WM_MBUTTONUP: case WM_RBUTTONUP: case WM_MOUSEMOVE: Tk_PointerEvent(hwnd, (short) LOWORD(lParam), (short) HIWORD(lParam)); return 1; case WM_CLOSE: case WM_SETFOCUS: case WM_KILLFOCUS: case WM_DESTROYCLIPBOARD: case WM_CHAR: case WM_SYSKEYDOWN: case WM_SYSKEYUP: case WM_KEYDOWN: case WM_KEYUP: GenerateXEvent(hwnd, message, wParam, lParam); return 1; case WM_MENUCHAR: GenerateXEvent(hwnd, message, wParam, lParam); /* MNC_CLOSE is the only one that looks right. This is a hack. */ *resultPtr = MAKELONG (0, MNC_CLOSE); return 1; } return 0;}/* *---------------------------------------------------------------------- * * GenerateXEvent -- * * This routine generates an X event from the corresponding * Windows event. * * Results: * None. * * Side effects: * Queues one or more X events. * *---------------------------------------------------------------------- */static voidGenerateXEvent(hwnd, message, wParam, lParam) HWND hwnd; UINT message; WPARAM wParam; LPARAM lParam;{ XEvent event; TkWindow *winPtr = (TkWindow *)Tk_HWNDToWindow(hwnd); if (!winPtr || winPtr->window == None) { return; } event.xany.serial = winPtr->display->request++; event.xany.send_event = False; event.xany.display = winPtr->display; event.xany.window = winPtr->window; switch (message) { case WM_PAINT: { PAINTSTRUCT ps; event.type = Expose; CkBeginPaint(hwnd, &ps); event.xexpose.x = ps.rcPaint.left; event.xexpose.y = ps.rcPaint.top; event.xexpose.width = ps.rcPaint.right - ps.rcPaint.left; event.xexpose.height = ps.rcPaint.bottom - ps.rcPaint.top; CkEndPaint(hwnd, &ps); event.xexpose.count = 0; break; } case WM_CLOSE: event.type = ClientMessage; event.xclient.message_type = Tk_InternAtom((Tk_Window) winPtr, "WM_PROTOCOLS"); event.xclient.format = 32; event.xclient.data.l[0] = Tk_InternAtom((Tk_Window) winPtr, "WM_DELETE_WINDOW"); break; case WM_SETFOCUS: case WM_KILLFOCUS: { TkWindow *otherWinPtr = (TkWindow *)Tk_HWNDToWindow((HWND) wParam); /* * Compare toplevel windows to avoid reporting focus * changes within the same toplevel. */ while (!(winPtr->flags & TK_TOP_LEVEL)) { winPtr = winPtr->parentPtr; if (winPtr == NULL) { return; } } while (otherWinPtr && !(otherWinPtr->flags & TK_TOP_LEVEL)) { otherWinPtr = otherWinPtr->parentPtr; } if (otherWinPtr == winPtr) { return; } event.xany.window = winPtr->window; event.type = (message == WM_SETFOCUS) ? FocusIn : FocusOut; event.xfocus.mode = NotifyNormal; event.xfocus.detail = NotifyNonlinear; break; } case WM_DESTROYCLIPBOARD: event.type = SelectionClear; event.xselectionclear.selection = Tk_InternAtom((Tk_Window)winPtr, "CLIPBOARD"); event.xselectionclear.time = TkpGetMS(); break; case WM_CHAR: case WM_SYSKEYDOWN: case WM_SYSKEYUP: case WM_KEYDOWN: case WM_KEYUP: { unsigned int state = GetState(message, wParam, lParam); Time time = TkpGetMS(); POINT clientPoint; POINTS rootPoint; /* Note: POINT and POINTS are different */ DWORD msgPos; /* * Compute the screen and window coordinates of the event. */ msgPos = GetMessagePos(); rootPoint = MAKEPOINTS(msgPos); clientPoint.x = rootPoint.x; clientPoint.y = rootPoint.y; ScreenToClient(hwnd, &clientPoint); /* * Set up the common event fields. */ event.xbutton.root = RootWindow(winPtr->display, winPtr->screenNum); event.xbutton.subwindow = None; event.xbutton.x = clientPoint.x; event.xbutton.y = clientPoint.y; event.xbutton.x_root = rootPoint.x; event.xbutton.y_root = rootPoint.y; event.xbutton.state = state; event.xbutton.time = time; event.xbutton.same_screen = True; /* * Now set up event specific fields. */ switch (message) { case WM_SYSKEYDOWN: case WM_KEYDOWN: /* * Check for translated characters in the event queue. * Setting xany.send_event to -1 indicates to the * Windows implementation of XLookupString that this * event was generated by windows and that the Windows * extension xkey.trans_chars is filled with the * characters that came from the TranslateMessage * call. If it is not -1, xkey.keycode is the * virtual key being sent programmatically by generic * code. */ event.type = KeyPress; event.xany.send_event = -1; event.xkey.keycode = wParam; GetTranslatedKey(&event.xkey); break; case WM_SYSKEYUP: case WM_KEYUP: /* * We don't check for translated characters on keyup * because Tk won't know what to do with them. Instead, we * wait for the WM_CHAR messages which will follow. */ event.type = KeyRelease; event.xkey.keycode = wParam; event.xkey.nchars = 0; break; case WM_CHAR: /* * Synthesize both a KeyPress and a KeyRelease. */ event.type = KeyPress; event.xany.send_event = -1; event.xkey.keycode = 0; event.xkey.nchars = 1; event.xkey.trans_chars[0] = (char) wParam; Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); event.type = KeyRelease; break; } break; } default: return; } Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);}/* *---------------------------------------------------------------------- * * GetState -- * * This function constructs a state mask for the mouse buttons * and modifier keys as they were before the event occured. * * Results: * Returns a composite value of all the modifier and button state * flags that were set at the time the event occurred. * * Side effects: * None. * *---------------------------------------------------------------------- */static unsigned intGetState(message, wParam, lParam) UINT message; /* Win32 message type */ WPARAM wParam; /* wParam of message, used if key message */ LPARAM lParam; /* lParam of message, used if key message */{ int mask; int prevState; /* 1 if key was previously down */ unsigned int state = TkWinGetModifierState(); /* * If the event is a key press or release, we check for modifier * keys so we can report the state of the world before the event. */ if (message == WM_SYSKEYDOWN || message == WM_KEYDOWN || message == WM_SYSKEYUP || message == WM_KEYUP) { mask = 0; prevState = HIWORD(lParam) & KF_REPEAT; switch(wParam) { case VK_SHIFT: mask = ShiftMask; break; case VK_CONTROL: mask = ControlMask; break; case VK_MENU: mask = Mod2Mask; break; case VK_CAPITAL: if (message == WM_SYSKEYDOWN || message == WM_KEYDOWN) { mask = LockMask; prevState = ((state & mask) ^ prevState) ? 0 : 1; } break; case VK_NUMLOCK: if (message == WM_SYSKEYDOWN || message == WM_KEYDOWN) { mask = Mod1Mask; prevState = ((state & mask) ^ prevState) ? 0 : 1; } break; case VK_SCROLL: if (message == WM_SYSKEYDOWN || message == WM_KEYDOWN) { mask = Mod3Mask; prevState = ((state & mask) ^ prevState) ? 0 : 1; } break; } if (prevState) { state |= mask; } else { state &= ~mask; } } return state;}/* *---------------------------------------------------------------------- * * GetTranslatedKey -- * * Retrieves WM_CHAR messages that are placed on the system queue * by the TranslateMessage system call and places them in the * given KeyPress event. * * Results: * Sets the trans_chars and nchars member of the key event. * * Side effects: * Removes any WM_CHAR messages waiting on the top of the system * event queue. * *---------------------------------------------------------------------- */static voidGetTranslatedKey(xkey) XKeyEvent *xkey;{ MSG msg; xkey->nchars = 0; while (xkey->nchars < XMaxTransChars && PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { if ((msg.message == WM_CHAR) || (msg.message == WM_SYSCHAR)) { xkey->trans_chars[xkey->nchars] = (char) msg.wParam; xkey->nchars++; GetMessage(&msg, NULL, 0, 0); /* * If this is a normal character message, we may need to strip * off the Alt modifier (e.g. Alt-digits). Note that we don't * want to do this for system messages, because those were * presumably generated as an Alt-char sequence (e.g. accelerator * keys). */ if ((msg.message == WM_CHAR) && (msg.lParam & 0x20000000)) { xkey->state = 0; } } else { break; } }}/* *---------------------------------------------------------------------- * * Tk_FreeXId -- * * This inteface is not needed under Windows. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */voidTk_FreeXId(display, xid) Display *display; XID xid;{}/* *---------------------------------------------------------------------- * * TkWinResendEvent -- * * This function converts an X event into a Windows event and * invokes the specified windo procedure. * * Results: * A standard Windows result. * * Side effects: * Invokes the window procedure * *---------------------------------------------------------------------- */LRESULTTkWinResendEvent(wndproc, hwnd, eventPtr) WNDPROC wndproc; HWND hwnd; XEvent *eventPtr;{ UINT msg; WPARAM wparam; LPARAM lparam; if (eventPtr->type == ButtonPress) { switch (eventPtr->xbutton.button) { case Button1: msg = WM_LBUTTONDOWN; wparam = MK_LBUTTON; break; case Button2: msg = WM_MBUTTONDOWN; wparam = MK_MBUTTON; break; case Button3: msg = WM_RBUTTONDOWN; wparam = MK_RBUTTON; break; default: return 0; } if (eventPtr->xbutton.state & Button1Mask) { wparam |= MK_LBUTTON; } if (eventPtr->xbutton.state & Button2Mask) { wparam |= MK_MBUTTON; } if (eventPtr->xbutton.state & Button3Mask) { wparam |= MK_RBUTTON; } if (eventPtr->xbutton.state & ShiftMask) { wparam |= MK_SHIFT; } if (eventPtr->xbutton.state & ControlMask) { wparam |= MK_CONTROL; } lparam = MAKELPARAM((short) eventPtr->xbutton.x, (short) eventPtr->xbutton.y); } else { return 0; } return CallWindowProc(wndproc, hwnd, msg, wparam, lparam);}/* *---------------------------------------------------------------------- * * TkpGetMS -- * * Return a relative time in milliseconds. It doesn't matter * when the epoch was. * * Results: * Number of milliseconds. * * Side effects: * None. * *---------------------------------------------------------------------- */unsigned longTkpGetMS(){ return GetCurrentTime();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -