Skip to content

Commit

Permalink
refactor: 优化鼠标消息处理部分的代码
Browse files Browse the repository at this point in the history
  • Loading branch information
yixy-only committed Nov 22, 2024
1 parent cbf5653 commit 74e97f2
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 247 deletions.
6 changes: 3 additions & 3 deletions include/ege.h
Original file line number Diff line number Diff line change
Expand Up @@ -747,9 +747,9 @@ struct mouse_msg
bool is_x1() const {return (flags & mouse_flag_x1) != 0;}
bool is_x2() const {return (flags & mouse_flag_x2) != 0;}

bool is_down() const {return msg == mouse_msg_down;}
bool is_up() const {return msg == mouse_msg_up;}
bool is_move() const {return msg == mouse_msg_move;}
bool is_down() const {return msg == mouse_msg_down; }
bool is_up() const {return msg == mouse_msg_up; }
bool is_move() const {return msg == mouse_msg_move; }
bool is_wheel() const {return msg == mouse_msg_wheel;}
};

Expand Down
9 changes: 4 additions & 5 deletions src/ege_head.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@
#define DEFAULT_CHARSET ANSI_CHARSET
#endif

#include "types.h"


namespace ege
{
Expand Down Expand Up @@ -200,10 +202,7 @@ struct _graph_setting
HANDLE threadui_handle;

/* 鼠标状态记录 */
int mouse_state_l, mouse_state_m, mouse_state_r, mouse_state_x1, mouse_state_x2;
int mouse_last_x, mouse_last_y;
int mouse_lastclick_x, mouse_lastclick_y;
int mouse_lastup_x, mouse_lastup_y;
Point mouse_pos;
int mouse_show;

LPMSG_KEY_PROC callback_key;
Expand All @@ -212,7 +211,7 @@ struct _graph_setting
void* callback_mouse_param;
LPCALLBACK_PROC callback_close;

/* 键盘状态记录 */
/* 按键状态记录 */
int keystatemap[MAX_KEY_VCODE];

/* egeControlBase */
Expand Down
4 changes: 2 additions & 2 deletions src/egegapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ int showmouse(int bShow)
int mousepos(int* x, int* y)
{
struct _graph_setting* pg = &graph_setting;
*x = pg->mouse_last_x;
*y = pg->mouse_last_y;
*x = pg->mouse_pos.x;
*y = pg->mouse_pos.y;
return 0;
}

Expand Down
200 changes: 68 additions & 132 deletions src/graphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
#include <stdio.h>
#include <stdlib.h>

#include <windowsx.h>

#include "ege_head.h"
#include "ege_common.h"
#include "ege_extension.h"
Expand Down Expand Up @@ -435,19 +437,72 @@ static void on_key(struct _graph_setting* pg, UINT message, unsigned long keycod
}

/*private function*/
static void push_mouse_msg(struct _graph_setting* pg, UINT message, WPARAM wparam, LPARAM lparam)
static void push_mouse_msg(struct _graph_setting* pg, UINT message, WPARAM wparam, LPARAM lparam, int time)
{
EGEMSG msg = {0};
msg.hwnd = pg->hwnd;
msg.message = message;
msg.wParam = wparam;
msg.lParam = lparam;
msg.mousekey = (pg->mouse_state_m << 2) | (pg->mouse_state_r << 1) | (pg->mouse_state_l << 0)
| (pg->mouse_state_x1 << 3) | (pg->mouse_state_x1 << 4);
msg.time = ::GetTickCount();

msg.mousekey |= pg->keystatemap[VK_LBUTTON] ? mouse_flag_left : 0;
msg.mousekey |= pg->keystatemap[VK_RBUTTON] ? mouse_flag_right : 0;
msg.mousekey |= pg->keystatemap[VK_MBUTTON] ? mouse_flag_mid : 0;
msg.mousekey |= pg->keystatemap[VK_XBUTTON1] ? mouse_flag_x1 : 0;
msg.mousekey |= pg->keystatemap[VK_XBUTTON2] ? mouse_flag_x2 : 0;

msg.time = time;
pg->msgmouse_queue->push(msg);
}

static void mouseProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
/* up 消息会后紧跟一条 move 消息,标记并将其忽略 */
static bool skipNextMoveMessage = false;
if ((message < WM_MOUSEFIRST) || (message > WM_MOUSELAST))
return;

_graph_setting* pg = &graph_setting;

Point curPos(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));

bool curMsgIsNeedToPush = true;

int key = 0;
mouse_msg msg = mouseMessageConvert(message, wParam, lParam, &key);

if (msg.is_up()) {
skipNextMoveMessage = true;
} else if (msg.is_move()) {
/* 忽略 up 消息后伴随的同位置 move 消息 */
if (skipNextMoveMessage && (curPos == pg->mouse_pos)) {
curMsgIsNeedToPush = false;
skipNextMoveMessage = false;
}
}

/* 鼠标按键动作 */
if (key != 0) {
pg->keystatemap[key] = msg.is_down();

/* 设置鼠标消息捕获 */
if (msg.is_down()) {
SetCapture(hWnd);
} else {
const int keyStateMask = MK_LBUTTON | MK_RBUTTON | MK_MBUTTON | MK_XBUTTON1 | MK_XBUTTON2;
if ((wParam & keyStateMask) == 0) {
ReleaseCapture();
}
}
}

if (curMsgIsNeedToPush && (hWnd == pg->hwnd)) {
push_mouse_msg(pg, message, wParam, lParam, GetMessageTime());
}

pg->mouse_pos = curPos;
}

/*private function*/
static LRESULT CALLBACK wndproc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
Expand Down Expand Up @@ -527,133 +582,15 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l
}
}
break;
case WM_LBUTTONDOWN:
case WM_LBUTTONDBLCLK:
pg->mouse_lastclick_x = (short int)((UINT)lParam & 0xFFFF);
pg->mouse_lastclick_y = (short int)((UINT)lParam >> 16);
pg->keystatemap[VK_LBUTTON] = 1;
SetCapture(hWnd);
pg->mouse_state_l = 1;
if (hWnd == pg->hwnd) {
push_mouse_msg(pg, message, wParam, lParam);
}
break;
case WM_MBUTTONDOWN:
case WM_MBUTTONDBLCLK:
pg->mouse_lastclick_x = (short int)((UINT)lParam & 0xFFFF);
pg->mouse_lastclick_y = (short int)((UINT)lParam >> 16);
pg->keystatemap[VK_MBUTTON] = 1;
SetCapture(hWnd);
pg->mouse_state_m = 1;
if (hWnd == pg->hwnd) {
push_mouse_msg(pg, message, wParam, lParam);
}
break;
case WM_RBUTTONDOWN:
case WM_RBUTTONDBLCLK:
pg->mouse_lastclick_x = (short int)((UINT)lParam & 0xFFFF);
pg->mouse_lastclick_y = (short int)((UINT)lParam >> 16);
pg->keystatemap[VK_RBUTTON] = 1;
SetCapture(hWnd);
pg->mouse_state_r = 1;
if (hWnd == pg->hwnd) {
push_mouse_msg(pg, message, wParam, lParam);
}
break;
case WM_XBUTTONDOWN:
case WM_XBUTTONDBLCLK:
pg->mouse_lastclick_x = (short int)((UINT)lParam & 0xFFFF);
pg->mouse_lastclick_y = (short int)((UINT)lParam >> 16);

if ((wParam >> 16) & 0x0001) {
pg->keystatemap[VK_XBUTTON1] = 1;
} else if ((wParam >> 16) & 0x0002){
pg->keystatemap[VK_XBUTTON2] = 1;
}
SetCapture(hWnd);
pg->mouse_state_x1 = 1;
if (hWnd == pg->hwnd) {
push_mouse_msg(pg, message, wParam, lParam);
}
break;
case WM_LBUTTONUP:
pg->mouse_lastup_x = (short int)((UINT)lParam & 0xFFFF);
pg->mouse_lastup_y = (short int)((UINT)lParam >> 16);
pg->mouse_state_l = 0;
pg->keystatemap[VK_LBUTTON] = 0;
if (pg->mouse_state_l == 0 && pg->mouse_state_m == 0 && pg->mouse_state_r == 0
&& pg->mouse_state_x1 && pg->mouse_state_x2) {
ReleaseCapture();
}
if (hWnd == pg->hwnd) {
push_mouse_msg(pg, message, wParam, lParam);
}
break;
case WM_MBUTTONUP:
pg->mouse_lastup_x = (short int)((UINT)lParam & 0xFFFF);
pg->mouse_lastup_y = (short int)((UINT)lParam >> 16);
pg->mouse_state_m = 0;
pg->keystatemap[VK_MBUTTON] = 0;
if (pg->mouse_state_l == 0 && pg->mouse_state_m == 0 && pg->mouse_state_r == 0
&& pg->mouse_state_x1 && pg->mouse_state_x2) {
ReleaseCapture();
}
if (hWnd == pg->hwnd) {
push_mouse_msg(pg, message, wParam, lParam);
}
break;
case WM_RBUTTONUP:
pg->mouse_lastup_x = (short int)((UINT)lParam & 0xFFFF);
pg->mouse_lastup_y = (short int)((UINT)lParam >> 16);
pg->mouse_state_r = 0;
pg->keystatemap[VK_RBUTTON] = 0;
if (pg->mouse_state_l == 0 && pg->mouse_state_m == 0 && pg->mouse_state_r == 0
&& pg->mouse_state_x1 && pg->mouse_state_x2) {
ReleaseCapture();
}
if (hWnd == pg->hwnd) {
push_mouse_msg(pg, message, wParam, lParam);
}
break;
case WM_XBUTTONUP:
pg->mouse_lastup_x = (short int)((UINT)lParam & 0xFFFF);
pg->mouse_lastup_y = (short int)((UINT)lParam >> 16);

if ((wParam >> 16) & 0x0001) {
pg->mouse_state_x1 = 0;
pg->keystatemap[VK_XBUTTON1] = 0;
} else if ((wParam >> 16) & 0x0002){
pg->mouse_state_x2 = 0;
pg->keystatemap[VK_XBUTTON2] = 0;
}
if (pg->mouse_state_l == 0 && pg->mouse_state_m == 0 && pg->mouse_state_r == 0
&& pg->mouse_state_x1 && pg->mouse_state_x2) {
ReleaseCapture();
}
if (hWnd == pg->hwnd) {
push_mouse_msg(pg, message, wParam, lParam);
}
break;
case WM_MOUSEMOVE:
pg->mouse_last_x = (short int)((UINT)lParam & 0xFFFF);
pg->mouse_last_y = (short int)((UINT)lParam >> 16);
if (hWnd == pg->hwnd && (pg->mouse_lastup_x != pg->mouse_last_x || pg->mouse_lastup_y != pg->mouse_last_y)) {
push_mouse_msg(pg, message, wParam, lParam);
}
break;
case WM_MOUSEWHEEL: {
POINT pt;
pt.x = (short int)((UINT)lParam & 0xFFFF);
pt.y = (short int)((UINT)lParam >> 16);
ScreenToClient(pg->hwnd, &pt);
pg->mouse_last_x = pt.x;
pg->mouse_last_y = pt.y;
lParam = ((unsigned short)(short int)pg->mouse_last_y << 16) | (unsigned short)(short int)pg->mouse_last_x;
}
if (hWnd == pg->hwnd) {
push_mouse_msg(pg, message, wParam, lParam);
}

case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_LBUTTONDBLCLK:
case WM_MBUTTONDOWN: case WM_MBUTTONUP: case WM_MBUTTONDBLCLK:
case WM_RBUTTONDOWN: case WM_RBUTTONUP: case WM_RBUTTONDBLCLK:
case WM_XBUTTONDOWN: case WM_XBUTTONUP: case WM_XBUTTONDBLCLK:
case WM_MOUSEMOVE: case WM_MOUSEWHEEL:
mouseProc(hWnd, message, wParam, lParam);
break;

case WM_SETCURSOR:
if (pg == pg_w) {
on_setcursor(pg, hWnd);
Expand Down Expand Up @@ -889,8 +826,7 @@ void initgraph(int* gdriver, int* gmode, const char* path)
POINT pt;
GetCursorPos(&pt);
ScreenToClient(pg->hwnd, &pt);
pg->mouse_last_x = pt.x;
pg->mouse_last_y = pt.y;
pg->mouse_pos = Point(pt.x, pt.y);

static egeControlBase _egeControlBase;

Expand Down
Loading

0 comments on commit 74e97f2

Please sign in to comment.