📄 desktop.c
字号:
if (sg_ptmi) {
plast = sg_ptmi;
while (plast->next) {
plast = plast->next;
}
plast->next = ptmi;
ptmi->prev = plast;
ptmi->next = NULL;
}
else {
sg_ptmi = ptmi;
ptmi->next = NULL;
ptmi->prev = NULL;
}
PopupMenuTrackProc (ptmi, MSG_INITMENU, 0, 0);
// Update all main windows' GCR info.
dskUpdateAllGCRInfoOnShowMenu (&ptmi->rc);
PopupMenuTrackProc (ptmi, MSG_SHOWMENU, 0, 0);
return 0;
}
static int dskEndTrackMenu(PTRACKMENUINFO ptmi)
{
PZORDERNODE pNode;
PMAINWIN pTemp;
PTRACKMENUINFO plast;
RECT rcInvalid;
if (sg_ptmi == ptmi)
sg_ptmi = NULL;
else {
plast = sg_ptmi;
while (plast->next) {
plast = plast->next;
}
plast->prev->next = NULL;
}
// Update all main windows' GCR info.
dskUpdateAllGCRInfoOnHideMenu ();
PopupMenuTrackProc (ptmi, MSG_HIDEMENU, 0, 0);
// Invalidate rect of affected main window.
pNode = TopMostWinZOrder.pTopMost;
while (pNode) {
pTemp = (PMAINWIN)(pNode->hWnd);
if (pTemp->dwStyle & WS_VISIBLE) {
if (IntersectRect (&rcInvalid, &ptmi->rc, (PRECT)(&pTemp->cl))) {
rcInvalid.left -= pTemp->cl;
rcInvalid.top -= pTemp->ct;
rcInvalid.right -= pTemp->cl;
rcInvalid.bottom -= pTemp->ct;
InvalidateRect ((HWND)pTemp, &rcInvalid, FALSE);
}
}
pNode = pNode->pNext;
}
pNode = MainWinZOrder.pTopMost;
while (pNode) {
pTemp = (PMAINWIN)(pNode->hWnd);
pTemp = (PMAINWIN)(pNode->hWnd);
if (pTemp->dwStyle & WS_VISIBLE) {
if (IntersectRect (&rcInvalid, &ptmi->rc, (PRECT)(&pTemp->cl))) {
rcInvalid.left -= pTemp->cl;
rcInvalid.top -= pTemp->ct;
rcInvalid.right -= pTemp->cl;
rcInvalid.bottom -= pTemp->ct;
InvalidateRect ((HWND)pTemp, &rcInvalid, FALSE);
}
}
pNode = pNode->pNext;
}
PopupMenuTrackProc (ptmi, MSG_ENDTRACKMENU, 0, 0);
return sg_ptmi == ptmi;
}
static BOOL dskForceCloseMenu ()
{
if (sg_ptmi == NULL) return FALSE;
SendNotifyMessage (sg_ptmi->hwnd, MSG_DEACTIVEMENU,
(WPARAM)sg_ptmi->pmb, (LPARAM)sg_ptmi->pmi);
PopupMenuTrackProc (sg_ptmi, MSG_CLOSEMENU, 0, 0);
sg_ptmi = NULL;
// Update all main windows' GCR info.
dskUpdateAllGCRInfoOnHideMenu ();
return TRUE;
}
/*********************** Hook support ****************************************/
#define NR_KEYHOOK 5
#define NR_MOUSEHOOK 5
#define MIN_MHHOOK NR_KEYHOOK
#define MAX_MHHOOK (NR_KEYHOOK + NR_MOUSEHOOK - 1)
static KEYHOOK keyhook [NR_KEYHOOK];
static MOUSEHOOK mousehook[NR_MOUSEHOOK];
static HHOOK dskRegisterKeyHook (HWND hWnd, KEYMSGHOOK hook)
{
int i;
for (i = 0; i<NR_KEYHOOK; i++) {
if (keyhook [i].hWnd == HWND_DESKTOP) {
keyhook [i].hWnd = hWnd;
keyhook [i].hook = hook;
return (HHOOK)i;
}
}
return HHOOK_INVALID;
}
static HHOOK dskRegisterMouseHook (HWND hWnd, MOUSEMSGHOOK hook)
{
int i;
for (i = 0; i<NR_MOUSEHOOK; i++) {
if (mousehook [i].hWnd == HWND_DESKTOP) {
mousehook [i].hWnd = hWnd;
mousehook [i].hook = hook;
return (HHOOK)(i + MIN_MHHOOK);
}
}
return HHOOK_INVALID;
}
static int dskUnregisterHook (HHOOK hHook)
{
int i;
if (hHook < 0 || hHook > MAX_MHHOOK)
return HHOOK_INVALID;
if (hHook >= MIN_MHHOOK) {
i = hHook - MIN_MHHOOK;
if (mousehook [i].hWnd == HWND_DESKTOP)
return HHOOK_INVALID;
mousehook [i].hWnd = HWND_DESKTOP;
mousehook [i].hook = NULL;
}
else {
i = hHook;
if (keyhook [i].hWnd == HWND_DESKTOP)
return HHOOK_INVALID;
keyhook [i].hWnd = HWND_DESKTOP;
keyhook [i].hook = NULL;
}
return HOOK_OK;
}
static void dskHandleKeyHooks (HWND hWnd,
int message, WPARAM wParam, LPARAM lParam)
{
int i;
for (i = 0; i < NR_KEYHOOK; i++) {
if (keyhook [i].hWnd != HWND_DESKTOP) {
(*(keyhook [i].hook)) (keyhook [i].hWnd,
message, wParam, lParam);
}
}
}
static void dskHandleMouseHooks (HWND hWnd,
int message, WPARAM wParam, LPARAM lParam)
{
int i;
for (i = 0; i < NR_MOUSEHOOK; i++) {
if (mousehook [i].hWnd != HWND_DESKTOP) {
(*(mousehook [i].hook)) (mousehook [i].hWnd,
message, wParam, lParam);
}
}
}
/*********************** Desktop window support ******************************/
inline PMAINWIN GetMainWinUnderPointer(int x, int y)
{
PZORDERNODE pNode;
PMAINWIN pTemp;
pNode = TopMostWinZOrder.pTopMost;
while(pNode)
{
pTemp = (PMAINWIN)pNode->hWnd;
if( PtInRect((PRECT)(&(pTemp->left)), x, y)
&& (pTemp->dwStyle & WS_VISIBLE))
return pTemp;
pNode = pNode->pNext;
}
pNode = MainWinZOrder.pTopMost;
while(pNode)
{
pTemp = (PMAINWIN)pNode->hWnd;
if( PtInRect((PRECT)(&(pTemp->left)), x, y)
&& (pTemp->dwStyle & WS_VISIBLE))
return pTemp;
pNode = pNode->pNext;
}
return NULL;
}
static int HandleSpecialKey (scancode)
{
switch (scancode) {
case SCANCODE_BACKSPACE:
TerminateLWEvent();
TerminateGDI();
exit (0);
break;
}
return 0;
}
void GUIAPI ExitGUISafely (int exitcode)
{
pthread_kill_other_threads_np ();
TerminateLWEvent();
TerminateGDI();
exit (exitcode);
}
static int KeyMessageHandler (int message, int scancode, DWORD status)
{
static int altdown = 0;
static int modal = 0;
PMAINWIN pNextWin;
if ((message == MSG_KEYDOWN) && (status & KS_ALT) && (status & KS_CTRL))
return HandleSpecialKey (scancode);
if (scancode == SCANCODE_LEFTALT ||
scancode == SCANCODE_RIGHTALT) {
if (message == MSG_KEYDOWN) {
altdown = 1;
return 0;
}
else {
altdown = 0;
if (modal == 1) {
modal = 0;
return 0;
}
}
}
if (altdown) {
if (message == MSG_KEYDOWN) {
if( scancode == SCANCODE_TAB) {
modal = 1;
if (sg_ptmi)
dskForceCloseMenu ();
pNextWin = dskGetNextVisibleWindow (pActiveMainWnd);
dskMoveToTopMost (pNextWin);
return 0;
}
else if (scancode == SCANCODE_ESCAPE) {
modal = 1;
if (pActiveMainWnd) {
#ifdef _DEBUG
fprintf (stderr, "Will be Closed: %p.\n", pActiveMainWnd);
#endif
PostMessage ((HWND)pActiveMainWnd, MSG_CLOSE, 0, 0);
return 0;
}
}
}
else if (modal == 1)
return 0;
}
if (scancode == SCANCODE_F10 ||
scancode == SCANCODE_LEFTALT ||
scancode == SCANCODE_RIGHTALT ||
altdown)
message = (message == MSG_KEYDOWN)?MSG_SYSKEYDOWN:MSG_SYSKEYUP;
else if (sg_hIMEWnd != HWND_DESKTOP) {
if (pActiveMainWnd && (pActiveMainWnd->dwExStyle & WS_EX_IMECOMPOSE)) {
dskHandleKeyHooks (sg_hIMEWnd, message,
(WPARAM)scancode, (LPARAM)status);
PostMessage (sg_hIMEWnd, message,
(WPARAM)scancode, (LPARAM)status);
return 0;
}
}
if (pActiveMainWnd) {
dskHandleKeyHooks ((HWND)pActiveMainWnd, message,
(WPARAM)scancode, (LPARAM)status);
PostMessage ((HWND)pActiveMainWnd, message,
(WPARAM)scancode, (LPARAM)status);
}
else {
dskHandleKeyHooks (HWND_DESKTOP, message,
(WPARAM)scancode, (LPARAM)status);
SendMessage (HWND_DESKTOP, MSG_DT_KEYOFF + message,
(WPARAM)scancode, (LPARAM)status);
}
return 0;
}
static int MouseMessageHandler(int message, WPARAM flags, int x, int y)
{
static PMAINWIN pOldUnderPointer = NULL;
static PMAINWIN pCaptured = (void*)HWND_INVALID;
PMAINWIN pUnderPointer;
int CapHitCode = HT_UNKNOWN;
int UndHitCode = HT_UNKNOWN;
int cx = 0, cy = 0;
if (message == MSG_WINDOWCHANGED) {
pCaptured = (void*) HWND_INVALID;
CapHitCode = HT_UNKNOWN;
pOldUnderPointer = NULL;
PostMessage (HWND_DESKTOP, MSG_MOUSEMOVE, 0, MAKELONG (x, y));
return 0;
}
dskHandleMouseHooks (HWND_DESKTOP, message, flags, MAKELONG (x, y));
if (hCaptureWnd) {
PostMessage (hCaptureWnd, message, flags|KS_CAPTURED, MAKELONG (x, y));
return 0;
}
if (pCaptured != (void*)HWND_INVALID && pCaptured != NULL) {
CapHitCode = SendAsyncMessage((HWND)pCaptured, MSG_HITTEST,
(WPARAM)x, (LPARAM)y);
}
pUnderPointer = GetMainWinUnderPointer(x, y);
if (pUnderPointer) {
UndHitCode = SendAsyncMessage((HWND)pUnderPointer, MSG_HITTEST,
(WPARAM)x, (LPARAM)y);
cx = x - pUnderPointer->cl;
cy = y - pUnderPointer->ct;
}
switch (message)
{
case MSG_MOUSEMOVE:
if (pCaptured != (void *)HWND_INVALID) {
if (pCaptured)
PostMessage((HWND)pCaptured, MSG_NCMOUSEMOVE,
CapHitCode, MAKELONG (x, y));
else
PostMessage(HWND_DESKTOP, MSG_DT_MOUSEMOVE,
pUnderPointer == NULL, MAKELONG (x, y));
break;
}
if(pUnderPointer == NULL) {
if (pOldUnderPointer) {
PostMessage ((HWND)pOldUnderPointer,
MSG_MOUSEMOVEIN, FALSE, 0);
PostMessage ((HWND)pOldUnderPointer,
MSG_NCMOUSEMOVE, HT_OUT, MAKELONG (x, y));
}
SetCursor(GetSystemCursor(IDC_ARROW));
}
else {
if(pOldUnderPointer && (pOldUnderPointer != pUnderPointer))
{
PostMessage ((HWND)pOldUnderPointer,
MSG_MOUSEMOVEIN, FALSE, 0);
PostMessage ((HWND)pOldUnderPointer,
MSG_NCMOUSEMOVE, HT_OUT, MAKELONG (x, y));
PostMessage ((HWND)pUnderPointer,
MSG_MOUSEMOVEIN, TRUE, 0);
}
if (pUnderPointer->dwStyle & WS_DISABLED) {
SetCursor(GetSystemCursor(IDC_ARROW));
break;
}
if(UndHitCode == HT_CLIENT)
{
SetCursor (pUnderPointer->hCursor);
PostMessage ((HWND)pUnderPointer, MSG_SETCURSOR,
UndHitCode, MAKELONG (cx, cy));
PostMessage((HWND)pUnderPointer, MSG_NCMOUSEMOVE,
UndHitCode, MAKELONG (x, y));
PostMessage((HWND)pUnderPointer, MSG_MOUSEMOVE,
flags, MAKELONG (cx, cy));
}
else
{
SetCursor (pUnderPointer->hCursor);
PostMessage ((HWND)pUnderPointer, MSG_NCSETCURSOR,
UndHitCode, MAKELONG (x, y));
PostMessage((HWND)pUnderPointer, MSG_NCMOUSEMOVE,
UndHitCode, MAKELONG (x, y));
}
}
break;
case MSG_LBUTTONDOWN:
case MSG_RBUTTONDOWN:
if (pUnderPointer) {
if (sg_ptmi)
dskForceCloseMenu ();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -