📄 desktop.c
字号:
free (pNode);
}
else {
while (pNode->pNext) {
if (pNode->pNext->hWnd == (HWND)pWin) {
pTemp = pNode->pNext->pNext;
free (pNode->pNext);
pNode->pNext = pTemp;
break;
}
pNode = pNode->pNext;
}
}
MainWinZOrder.nNumber--;
}
return pActiveMainWnd;
}
static BOOL dskUpdateWindow (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 void dskUpdateAllGCRInfoOnHideMenu ();
static int dskScrollMainWindow (PMAINWIN pWin, PSCROLLWINDOWINFO pswi)
{
HDC hdc;
RECT rcClient, rcInter, rcInvalid, rcScroll;
PZORDERNODE pNode;
PMAINWIN pTemp;
BOOL inved = FALSE;
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);
hdc = GetClientDC ((HWND)pWin);
SelectClipRect (hdc, &rcScroll);
BitBlt (hdc, 0, 0, rcClient.right, rcClient.bottom,
hdc, pswi->iOffx, pswi->iOffy, 0);
ReleaseDC (hdc);
if (!(pWin->dwExStyle & WS_EX_TOPMOST)) {
WindowToScreen ((HWND)pWin, &rcClient.left, &rcClient.top);
WindowToScreen ((HWND)pWin, &rcClient.right, &rcClient.bottom);
pNode = TopMostWinZOrder.pTopMost;
while (pNode) {
pTemp = (PMAINWIN)(pNode->hWnd);
if (pTemp != pWin && pTemp->dwStyle & WS_VISIBLE) {
if (IntersectRect (&rcInter,
&rcClient, (PRECT)(&pTemp->left))) {
ScreenToClient ((HWND)pWin,
&rcInter.left, &rcInter.top);
ScreenToClient ((HWND)pWin,
&rcInter.right, &rcInter.bottom);
if (pswi->iOffx < 0) {
rcInter.right = rcInter.left;
rcInter.left += pswi->iOffx;
}
else if (pswi->iOffx > 0) {
rcInter.left = rcInter.right;
rcInter.right += pswi->iOffx;
}
if (pswi->iOffy < 0) {
rcInter.bottom = rcInter.top;
rcInter.top += pswi->iOffy;
}
else if (pswi->iOffy > 0) {
rcInter.top = rcInter.bottom;
rcInter.bottom += pswi->iOffy;
}
rcInter.right += 2;
rcInter.bottom += 2;
wndInvalidateRect ((HWND)pWin, &rcInter, TRUE);
inved = TRUE;
}
}
pNode = pNode->pNext;
}
}
if (pswi->iOffx < 0) {
rcInvalid.top = 0;
rcInvalid.bottom = pWin->cb - pWin->ct;
rcInvalid.right = pWin->cr - pWin->cl;
rcInvalid.left = rcInvalid.right + pswi->iOffx;
wndInvalidateRect ((HWND)pWin, &rcInvalid, TRUE);
inved = TRUE;
}
else if (pswi->iOffx > 0) {
rcInvalid.top = 0;
rcInvalid.bottom = pWin->cb - pWin->ct;
rcInvalid.left = 0;
rcInvalid.right = pswi->iOffx;
wndInvalidateRect ((HWND)pWin, &rcInvalid, TRUE);
inved = TRUE;
}
if (pswi->iOffy < 0) {
rcInvalid.left = 0;
rcInvalid.right = pWin->cr - pWin->cl;
rcInvalid.bottom = pWin->cb - pWin->ct;
rcInvalid.top = rcInvalid.bottom + pswi->iOffy;
wndInvalidateRect ((HWND)pWin, &rcInvalid, TRUE);
inved = TRUE;
}
else if (pswi->iOffy > 0) {
rcInvalid.left = 0;
rcInvalid.right = pWin->cr - pWin->cl;
rcInvalid.top = 0;
rcInvalid.bottom = pswi->iOffy;
wndInvalidateRect ((HWND)pWin, &rcInvalid, TRUE);
inved = TRUE;
}
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;
int nCount, nInvCount; // number of invalid rects.
int i;
PZORDERNODE pNode;
PMAINWIN pTemp;
HDC hdc, hMemDC;
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, &sg_rcScr);
// save window rect.
hdc = GetDC ((HWND)pWin);
hMemDC = CreateCompatibleDC (hdc);
BitBlt (hdc, 0, 0, RECTW(oldWinRect), RECTH(oldWinRect), hMemDC, 0, 0, 0);
ReleaseDC (hdc);
// Update all affected windows' GCR info.
SendAsyncMessage ((HWND)pWin, MSG_CHANGESIZE, (WPARAM)(prcExpect), 0);
dskUpdateAllGCRInfoOnHideMenu ();
// put window rect.
hdc = GetDC ((HWND)pWin);
// ScreenCopy (oldWinRect.left, oldWinRect.top, hdc, 0, 0);
BitBlt (hMemDC, 0, 0,
RECTW (oldWinRect), RECTH (oldWinRect),
hdc, 0, 0, 0);
DeleteCompatibleDC (hMemDC);
ReleaseDC (hdc);
// when old window rect out of date.
for (i=0; i<nInvCount; i++)
if (dskUpdateWindow (pWin, rcInv + i, &oldWinRect, &oldClientRect))
SendAsyncMessage ((HWND)pWin, MSG_PAINT, 0, 0);
if (!(pWin->dwExStyle & WS_EX_TOPMOST)) {
pNode = TopMostWinZOrder.pTopMost;
while (pNode) {
pTemp = (PMAINWIN)(pNode->hWnd);
if (pTemp != pWin && pTemp->dwStyle & WS_VISIBLE) {
dskUpdateWindow (pWin, (PRECT)(&pTemp->left),
&oldWinRect, &oldClientRect);
// if (dskUpdateWindow (pWin, (PRECT)(&pTemp->left),
// &oldWinRect, &oldClientRect))
// SendAsyncMessage ((HWND)pWin, MSG_PAINT, 0, 0);
}
pNode = pNode->pNext;
}
}
// when other windows' rect out of date.
for (i=0; i<nCount; i++) {
if (pWin->dwExStyle & WS_EX_TOPMOST) {
pNode = TopMostWinZOrder.pTopMost;
while (pNode) {
pTemp = (PMAINWIN)(pNode->hWnd);
if (pTemp != pWin && pTemp->dwStyle & WS_VISIBLE)
dskUpdateWindow (pTemp, rc + i,
(PRECT)(&pTemp->left), (PRECT)(&pTemp->cl));
// if (dskUpdateWindow (pTemp, rc + i,
// (PRECT)(&pTemp->left), (PRECT)(&pTemp->cl)))
// SendAsyncMessage ((HWND)pTemp, MSG_PAINT, 0, 0);
pNode = pNode->pNext;
}
}
pNode = MainWinZOrder.pTopMost;
while (pNode) {
pTemp = (PMAINWIN)(pNode->hWnd);
if (pTemp != pWin && pTemp->dwStyle & WS_VISIBLE)
dskUpdateWindow (pTemp, rc + i,
(PRECT)(&pTemp->left), (PRECT)(&pTemp->cl));
pNode = pNode->pNext;
}
IntersectRect (&rcInter, rc + i, &sg_rcScr);
DesktopProc (HWND_DESKTOP, MSG_ERASEDESKTOP, 0, (LPARAM)(&rcInter));
}
{
MSG msg;
// remove any mouse moving messages in mesasge queue.
while (PeekPostMessage (&msg, HWND_DESKTOP,
MSG_MOUSEMOVE, MSG_MOUSEMOVE, PM_REMOVE))
{ };
}
}
static void dskUpdateAllGCRInfoOnShowMenu (RECT* prc)
{
PZORDERNODE pNode;
PGCRINFO pGCRInfo;
// update all main windows' global clip region
pNode = TopMostWinZOrder.pTopMost;
while (pNode)
{
if (((PMAINWIN)(pNode->hWnd))->dwStyle & WS_VISIBLE) {
pGCRInfo = &((PMAINWIN)(pNode->hWnd))->GCRInfo;
pthread_mutex_lock (&pGCRInfo->lock);
SubtractClipRect (&pGCRInfo->crgn, prc);
pGCRInfo->age ++;
pthread_mutex_unlock (&pGCRInfo->lock);
}
pNode = pNode->pNext;
}
pNode = MainWinZOrder.pTopMost;
while (pNode)
{
if (((PMAINWIN)(pNode->hWnd))->dwStyle & WS_VISIBLE) {
pGCRInfo = &((PMAINWIN)(pNode->hWnd))->GCRInfo;
pthread_mutex_lock (&pGCRInfo->lock);
SubtractClipRect (&pGCRInfo->crgn, prc);
pGCRInfo->age ++;
pthread_mutex_unlock (&pGCRInfo->lock);
}
pNode = pNode->pNext;
}
// update desktop's global clip region.
pthread_mutex_lock (&sg_ScrGCRInfo.lock);
SubtractClipRect (&sg_ScrGCRInfo.crgn, prc);
sg_ScrGCRInfo.age ++;
pthread_mutex_unlock (&sg_ScrGCRInfo.lock);
}
static void dskUpdateAllGCRInfoOnHideMenu ()
{
PZORDERNODE pNode, pAffected;
PGCRINFO pGCRInfo;
RECT rcTemp;
PMAINWIN pTemp;
PTRACKMENUINFO ptmi;
pAffected = TopMostWinZOrder.pTopMost;
while (pAffected){
pTemp = (PMAINWIN)(pAffected->hWnd);
if (pTemp->dwStyle & WS_VISIBLE) {
pGCRInfo = &pTemp->GCRInfo;
pthread_mutex_lock (&pGCRInfo->lock);
IntersectRect (&rcTemp, (PRECT)(&pTemp->left), &sg_rcScr);
SetClipRgn (&pGCRInfo->crgn, &rcTemp);
pNode = TopMostWinZOrder.pTopMost;
while (pNode != pAffected) {
pTemp = (PMAINWIN)(pNode->hWnd);
if (pTemp->dwStyle & WS_VISIBLE)
SubtractClipRect (&pGCRInfo->crgn, (PRECT)(&pTemp->left));
pNode = pNode->pNext;
}
ptmi = sg_ptmi;
while (ptmi) {
SubtractClipRect (&pGCRInfo->crgn, &ptmi->rc);
ptmi = ptmi->next;
}
pGCRInfo->age ++;
pthread_mutex_unlock (&pGCRInfo->lock);
}
pAffected = pAffected->pNext;
}
pAffected = MainWinZOrder.pTopMost;
while (pAffected){
pTemp = (PMAINWIN)(pAffected->hWnd);
if (pTemp->dwStyle & WS_VISIBLE) {
pGCRInfo = &pTemp->GCRInfo;
pthread_mutex_lock (&pGCRInfo->lock);
IntersectRect (&rcTemp, (PRECT)(&pTemp->left), &sg_rcScr);
SetClipRgn (&pGCRInfo->crgn, &rcTemp);
pNode = TopMostWinZOrder.pTopMost;
while (pNode) {
pTemp = (PMAINWIN)(pNode->hWnd);
if (pTemp->dwStyle & WS_VISIBLE)
SubtractClipRect (&pGCRInfo->crgn, (PRECT)(&pTemp->left));
pNode = pNode->pNext;
}
pNode = MainWinZOrder.pTopMost;
while (pNode != pAffected) {
pTemp = (PMAINWIN)(pNode->hWnd);
if (pTemp->dwStyle & WS_VISIBLE)
SubtractClipRect (&pGCRInfo->crgn, (PRECT)(&pTemp->left));
pNode = pNode->pNext;
}
ptmi = sg_ptmi;
while (ptmi) {
SubtractClipRect (&pGCRInfo->crgn, &ptmi->rc);
ptmi = ptmi->next;
}
pGCRInfo->age ++;
pthread_mutex_unlock (&pGCRInfo->lock);
}
pAffected = pAffected->pNext;
}
// update desktop's global clip region.
pthread_mutex_lock (&sg_ScrGCRInfo.lock);
SetClipRgn (&sg_ScrGCRInfo.crgn, &sg_rcScr);
pNode = TopMostWinZOrder.pTopMost;
while (pNode) {
pTemp = (PMAINWIN)(pNode->hWnd);
if (pTemp->dwStyle & WS_VISIBLE)
SubtractClipRect (&sg_ScrGCRInfo.crgn, (PRECT)(&pTemp->left));
pNode = pNode->pNext;
}
pNode = MainWinZOrder.pTopMost;
while (pNode) {
pTemp = (PMAINWIN)(pNode->hWnd);
if (pTemp->dwStyle & WS_VISIBLE)
SubtractClipRect (&sg_ScrGCRInfo.crgn, (PRECT)(&pTemp->left));
pNode = pNode->pNext;
}
ptmi = sg_ptmi;
while (ptmi) {
SubtractClipRect (&sg_ScrGCRInfo.crgn, &ptmi->rc);
ptmi = ptmi->next;
}
sg_ScrGCRInfo.age ++;
pthread_mutex_unlock (&sg_ScrGCRInfo.lock);
}
// call back proc of tracking menu.
// defined in Menu module.
int PopupMenuTrackProc (PTRACKMENUINFO ptmi,
int message, WPARAM wParam, LPARAM lParam);
static int dskTrackPopupMenu(PTRACKMENUINFO ptmi)
{
PTRACKMENUINFO plast;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -