📄 desktop-comm.c
字号:
__mg_ptmi = NULL;
// Update all main windows' GCR info.
dskUpdateAllGCRInfoOnHideMenu ();
return TRUE;
}
static BOOL dskUpdateOldMainWindow (PMAINWIN pWin,
const RECT* prcInv, const RECT* prcWin, const RECT* prcClient)
{
RECT rcInter;
if (IntersectRect (&rcInter, prcInv, prcWin)) {
rcInter.left -= prcWin->left;
rcInter.top -= prcWin->top;
rcInter.right -= prcWin->left;
rcInter.bottom -= prcWin->top;
SendAsyncMessage ((HWND)pWin, MSG_NCPAINT, 0, (LPARAM)(&rcInter));
if (IntersectRect (&rcInter, prcInv, prcClient)) {
rcInter.left -= prcClient->left;
rcInter.top -= prcClient->top;
rcInter.right -= prcClient->left;
rcInter.bottom -= prcClient->top;
InvalidateRect ((HWND)pWin, &rcInter, TRUE);
return TRUE;
}
}
return FALSE;
}
static BOOL dskUpdateWindow (PMAINWIN pWin,
const RECT* prcInv, const RECT* prcWin, const RECT* prcClient)
{
RECT rcInter, rcInv;
if (IntersectRect (&rcInter, prcInv, prcWin)) {
dskScreenToWindow (pWin, &rcInter, &rcInv);
SendAsyncMessage ((HWND)pWin, MSG_NCPAINT, 0, (LPARAM)(&rcInv));
if (IntersectRect (&rcInter, prcInv, prcClient)) {
dskScreenToClient (pWin, &rcInter, &rcInv);
InvalidateRect ((HWND)pWin, &rcInv, TRUE);
return TRUE;
}
}
return FALSE;
}
static int dskScrollMainWindow (PMAINWIN pWin, PSCROLLWINDOWINFO pswi)
{
HDC hdc;
RECT rcClient, rcScreen, rcInvalid, rcScroll;
BOOL inved = FALSE;
PCLIPRECT pcrc;
rcClient.left = 0;
rcClient.top = 0;
rcClient.right = pWin->cr - pWin->cl;
rcClient.bottom = pWin->cb - pWin->ct;
if (pswi->rc1)
IntersectRect (&rcScroll, pswi->rc1, &rcClient);
else
rcScroll = rcClient;
if (pswi->rc2)
IntersectRect (&rcScroll, pswi->rc2, &rcScroll);
dskClientToScreen (pWin, &rcScroll, &rcScreen);
hdc = GetClientDC ((HWND)pWin);
pcrc = GetGCRgnInfo ((HWND)pWin)->crgn.head;
while (pcrc) {
RECT rcMove;
if (!IntersectRect (&rcMove, &pcrc->rc, &rcScreen)) {
pcrc = pcrc->next;
continue;
}
dskScreenToClient (pWin, &rcMove, &rcMove);
if (!IntersectRect (&rcMove, &rcMove, &rcScroll)) {
pcrc = pcrc->next;
continue;
}
SelectClipRect (hdc, &rcMove);
BitBlt (hdc, rcMove.left, rcMove.top,
rcMove.right - rcMove.left,
rcMove.bottom - rcMove.top,
hdc, pswi->iOffx + rcMove.left, pswi->iOffy + rcMove.top, 0);
pcrc = pcrc->next;
}
ReleaseDC (hdc);
#if defined(_LITE_VERSION) && !defined(_STAND_ALONE)
// update region covered by the server clipping rects.
if (!mgIsServer) {
int i;
RECT* crcs = SHAREDRES_SCRINFO.clip_rects;
for (i = 0; i < MAX_SRV_CLIP_RECTS; i++) {
if (!IsRectEmpty (crcs + i)) {
if (IntersectRect (&rcInvalid, crcs + i, &rcScreen)) {
dskScreenToClient (pWin, &rcInvalid, &rcInvalid);
OffsetRect (&rcInvalid, pswi->iOffx, pswi->iOffy);
wndInvalidateRect ((HWND)pWin, &rcInvalid, TRUE);
inved = TRUE;
}
}
}
}
#endif
pcrc = GetGCRgnInfo ((HWND)pWin)->crgn.head;
while (pcrc) {
RECT rcMove;
if (!IntersectRect (&rcMove, &pcrc->rc, &rcScreen)) {
pcrc = pcrc->next;
continue;
}
dskScreenToClient (pWin, &rcMove, &rcMove);
rcInvalid = rcMove;
if (pswi->iOffx < 0) {
rcInvalid.left = rcInvalid.right + pswi->iOffx;
wndInvalidateRect ((HWND)pWin, &rcInvalid, TRUE);
inved = TRUE;
}
else if (pswi->iOffx > 0) {
rcInvalid.right = rcInvalid.left + pswi->iOffx;
wndInvalidateRect ((HWND)pWin, &rcInvalid, TRUE);
inved = TRUE;
}
rcInvalid = rcMove;
if (pswi->iOffy < 0) {
rcInvalid.top = rcInvalid.bottom + pswi->iOffy;
wndInvalidateRect ((HWND)pWin, &rcInvalid, TRUE);
inved = TRUE;
}
else if (pswi->iOffy > 0) {
rcInvalid.bottom = rcInvalid.top + pswi->iOffy;
wndInvalidateRect ((HWND)pWin, &rcInvalid, TRUE);
inved = TRUE;
}
pcrc = pcrc->next;
}
if (inved)
PostMessage ((HWND)pWin, MSG_PAINT, 0, 0);
return 0;
}
static void dskMoveMainWindow (PMAINWIN pWin, const RECT* prcExpect)
{
RECT oldWinRect, oldClientRect, src; // old window rect.
RECT rc[4], rcInv[4]; // invalid rects.
RECT rcInter, rcTemp, rcTempClient;
int nCount, nInvCount; // number of invalid rects.
int i;
PZORDERNODE pNode;
PMAINWIN pTemp;
HDC hdc;
memcpy (&src, &pWin->left, sizeof (RECT));
memcpy (&oldClientRect, &pWin->cl, sizeof (RECT));
oldWinRect = src;
// calculate invalid rect of other windows
nCount = SubtractRect (rc, &src, prcExpect);
// calculate invalid rect of moving window
nInvCount = SubtractRect (rcInv, &src, &g_rcScr);
// Update all affected windows' GCR info.
SendAsyncMessage ((HWND)pWin, MSG_CHANGESIZE, (WPARAM)(prcExpect), 0);
dskUpdateAllGCRInfoOnHideMenu ();
// Move window content.
hdc = GetDC ((HWND)pWin);
BitBlt (HDC_SCREEN, oldWinRect.left, oldWinRect.top,
RECTW (oldWinRect), RECTH (oldWinRect),
hdc, 0, 0, 0);
ReleaseDC (hdc);
#if defined(_LITE_VERSION) && !defined(_STAND_ALONE)
if (mgIsServer) {
scr_del_clip_rect (pWin->scr_idx);
dskGetWindowRectInScreen (pWin, &rcTemp);
pWin->scr_idx = scr_add_clip_rect (&rcTemp);
}
#endif
// when old window rect out of date.
for (i=0; i<nInvCount; i++)
dskUpdateOldMainWindow (pWin, rcInv + i, &oldWinRect, &oldClientRect);
#if defined(_LITE_VERSION) && !defined(_STAND_ALONE)
// update region covered by the server clipping rects.
if (!mgIsServer) {
int i;
RECT* crcs = SHAREDRES_SCRINFO.clip_rects;
for (i = 0; i < MAX_SRV_CLIP_RECTS; i++) {
if (!IsRectEmpty (crcs + i))
dskUpdateOldMainWindow (pWin, crcs + i, &oldWinRect, &oldClientRect);
}
}
#endif
// update region covered by the topmost windows.
if (!(pWin->dwExStyle & WS_EX_TOPMOST)) {
pNode = sg_TopMostWinZOrder.pTopMost;
while (pNode) {
pTemp = (PMAINWIN)(pNode->hWnd);
if (pTemp != pWin && pTemp->dwStyle & WS_VISIBLE) {
dskGetWindowRectInScreen (pTemp, &rcTemp);
dskUpdateOldMainWindow (pWin, &rcTemp, &oldWinRect, &oldClientRect);
}
pNode = pNode->pNext;
}
}
// when other windows run out of date.
for (i=0; i<nCount; i++) {
if (pWin->dwExStyle & WS_EX_TOPMOST) {
pNode = sg_TopMostWinZOrder.pTopMost;
while (pNode) {
pTemp = (PMAINWIN)(pNode->hWnd);
if (pTemp != pWin && pTemp->dwStyle & WS_VISIBLE) {
dskGetWindowRectInScreen (pTemp, &rcTemp);
dskGetClientRectInScreen (pTemp, &rcTempClient);
dskUpdateWindow (pTemp, rc + i, &rcTemp, &rcTempClient);
}
pNode = pNode->pNext;
}
}
pNode = sg_MainWinZOrder.pTopMost;
while (pNode) {
pTemp = (PMAINWIN)(pNode->hWnd);
if (pTemp != pWin && pTemp->dwStyle & WS_VISIBLE) {
dskGetWindowRectInScreen (pTemp, &rcTemp);
dskGetClientRectInScreen (pTemp, &rcTempClient);
dskUpdateWindow (pTemp, rc + i, &rcTemp, &rcTempClient);
}
pNode = pNode->pNext;
}
IntersectRect (&rcInter, rc + i, &g_rcDesktop);
DesktopWinProc (HWND_DESKTOP, MSG_ERASEDESKTOP, 0, (LPARAM)(&rcInter));
}
{
MSG msg;
// remove any mouse moving messages in mesasge queue.
while (PeekPostMessage (&msg, (HWND)pWin,
MSG_MOUSEMOVE, MSG_MOUSEMOVE, PM_REMOVE))
{ };
}
}
/*********************** Hook support ****************************************/
static HOOKINFO keyhook;
static HOOKINFO mousehook;
static MSGHOOK dskRegisterKeyHook (void* context, MSGHOOK hook)
{
MSGHOOK old_hook = keyhook.hook;
keyhook.context = context;
keyhook.hook = hook;
return old_hook;
}
static MSGHOOK dskRegisterMouseHook (void* context, MSGHOOK hook)
{
MSGHOOK old_hook = mousehook.hook;
mousehook.context = context;
mousehook.hook = hook;
return old_hook;
}
static int dskHandleKeyHooks (HWND dst_wnd, int message, WPARAM wParam, LPARAM lParam)
{
int ret = HOOK_GOON;
if (keyhook.hook) {
ret = keyhook.hook (keyhook.context, dst_wnd, message, wParam, lParam);
}
return ret;
}
static int dskHandleMouseHooks (HWND dst_wnd, int message, WPARAM wParam, LPARAM lParam)
{
int ret = HOOK_GOON;
if (mousehook.hook) {
ret = mousehook.hook (mousehook.context, dst_wnd, message, wParam, lParam);
}
return ret;
}
/*********************** Desktop window support ******************************/
PMAINWIN GetMainWindowPtrUnderPoint (int x, int y)
{
PZORDERNODE pNode;
PMAINWIN pTemp;
RECT rcTemp;
pNode = sg_TopMostWinZOrder.pTopMost;
while (pNode)
{
pTemp = (PMAINWIN)pNode->hWnd;
dskGetWindowRectInScreen (pTemp, &rcTemp);
if (PtInRect (&rcTemp, x, y)
&& (pTemp->dwStyle & WS_VISIBLE)) {
return pTemp;
}
pNode = pNode->pNext;
}
pNode = sg_MainWinZOrder.pTopMost;
while (pNode)
{
pTemp = (PMAINWIN)pNode->hWnd;
dskGetWindowRectInScreen (pTemp, &rcTemp);
if (PtInRect (&rcTemp, x, y)
&& (pTemp->dwStyle & WS_VISIBLE)) {
return pTemp;
}
pNode = pNode->pNext;
}
return NULL;
}
static int HandleSpecialKey (int scancode)
{
switch (scancode) {
case SCANCODE_BACKSPACE:
TerminateGUI (-1);
#ifndef __UCOSII__
exit (2);
#endif
break;
}
return 0;
}
void GUIAPI ExitGUISafely (int exitcode)
{
TerminateGUI ((exitcode > 0) ? -exitcode : exitcode);
#ifndef __UCOSII__
exit (2);
#endif
}
static int KeyMessageHandler (int message, int scancode, DWORD status)
{
PMAINWIN pNextWin;
static int mg_altdown = 0;
static int mg_modal = 0;
if ((message == MSG_KEYDOWN) && (status & KS_ALT) && (status & KS_CTRL))
return HandleSpecialKey (scancode);
if (scancode == SCANCODE_LEFTALT ||
scancode == SCANCODE_RIGHTALT) {
if (message == MSG_KEYDOWN) {
mg_altdown = 1;
return 0;
}
else {
mg_altdown = 0;
if (mg_modal == 1) {
mg_modal = 0;
return 0;
}
}
}
if (mg_altdown) {
if (message == MSG_KEYDOWN) {
if( scancode == SCANCODE_TAB) {
mg_modal = 1;
if (__mg_ptmi)
dskForceCloseMenu ();
pNextWin = dskGetNextVisibleMainWindow (__mg_active_mainwnd);
dskMoveToTopMost (pNextWin, RCTM_KEY, 0);
dskChangActiveWindow (pNextWin);
return 0;
}
else if (scancode == SCANCODE_ESCAPE) {
mg_modal = 1;
if (__mg_active_mainwnd) {
#ifdef _DEBUG
fprintf (stderr, "Will be Closed: %p.\n", __mg_active_mainwnd);
#endif
PostMessage ((HWND)__mg_active_mainwnd, MSG_CLOSE, 0, 0);
return 0;
}
}
}
else if (mg_modal == 1)
return 0;
}
if (scancode == SCANCODE_LEFTALT
|| scancode == SCANCODE_RIGHTALT || mg_altdown) {
if (message == MSG_KEYDOWN)
message = MSG_SYSKEYDOWN;
else {
message = MSG_SYSKEYUP;
mg_altdown = 0;
}
}
#ifdef _LITE_VERSION
if (__mg_ime_wnd) {
if (dskHandleKeyHooks (__mg_ime_wnd,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -