📄 desktop-comm.c
字号:
clip_by_windows (&sg_TopMostWinZOrder, pTemp);
clip_by_all_above_this (&sg_MainWinZOrder, pTemp);
}
else
clip_by_all_above_this (&sg_TopMostWinZOrder, pTemp);
end_clip_window (pTemp);
if (IntersectRect (&rcTemp, rcWin, &rcTemp)) {
dskScreenToWindow (pTemp, &rcTemp, &rcInv);
SendAsyncMessage ((HWND)pTemp, MSG_NCPAINT, 0, (LPARAM)(&rcInv));
dskScreenToClient (pTemp, &rcTemp, &rcInv);
InvalidateRect ((HWND)pTemp, &rcInv, TRUE);
}
}
pAffected = pAffected->pNext;
}
}
static void recalc_windows (ZORDERINFO* zorder, RECT* rcWin)
{
PZORDERNODE pAffected;
RECT rcTemp, rcInv;
PMAINWIN pTemp;
pAffected = zorder->pTopMost;
while (pAffected){
pTemp = (PMAINWIN)(pAffected->hWnd);
if (pTemp->dwStyle & WS_VISIBLE) {
start_clip_window (pTemp);
dskGetWindowRectInScreen (pTemp, &rcTemp);
reset_window (pTemp, &rcTemp);
clip_by_windows (&sg_TopMostWinZOrder, pTemp);
clip_by_all_above_this (&sg_MainWinZOrder, pTemp);
end_clip_window (pTemp);
if (IntersectRect (&rcTemp, rcWin, &rcTemp)) {
dskScreenToWindow (pTemp, &rcTemp, &rcInv);
SendAsyncMessage ((HWND)pTemp, MSG_NCPAINT, 0, (LPARAM)(&rcInv));
dskScreenToClient (pTemp, &rcTemp, &rcInv);
InvalidateRect ((HWND)pTemp, &rcInv, TRUE);
}
}
pAffected = pAffected->pNext;
}
}
static void recalc_desktop (PTRACKMENUINFO ptmi)
{
PZORDERNODE pNode;
RECT rcTemp;
PMAINWIN pTemp;
// update desktop's global clip region.
#ifndef _LITE_VERSION
pthread_mutex_lock (&sg_ScrGCRInfo.lock);
#endif
SetClipRgn (&sg_ScrGCRInfo.crgn, &g_rcDesktop);
pNode = sg_TopMostWinZOrder.pTopMost;
while (pNode) {
pTemp = (PMAINWIN)(pNode->hWnd);
if (pTemp->dwStyle & WS_VISIBLE) {
dskGetWindowRectInScreen (pTemp, &rcTemp);
SubtractClipRect (&sg_ScrGCRInfo.crgn, &rcTemp);
}
pNode = pNode->pNext;
}
pNode = sg_MainWinZOrder.pTopMost;
while (pNode) {
pTemp = (PMAINWIN)(pNode->hWnd);
if (pTemp->dwStyle & WS_VISIBLE) {
dskGetWindowRectInScreen (pTemp, &rcTemp);
SubtractClipRect (&sg_ScrGCRInfo.crgn, &rcTemp);
}
pNode = pNode->pNext;
}
while (ptmi) {
SubtractClipRect (&sg_ScrGCRInfo.crgn, &ptmi->rc);
ptmi = ptmi->next;
}
#if defined(_LITE_VERSION) && !defined(_STAND_ALONE)
if (mgIsServer && mgTopmostLayer) {
MG_Client* client = mgTopmostLayer->cli_head;
while (client) {
SubtractClipRect (&sg_ScrGCRInfo.crgn, &client->rc);
client = client->next;
}
}
#endif
sg_ScrGCRInfo.age ++;
#ifndef _LITE_VERSION
pthread_mutex_unlock (&sg_ScrGCRInfo.lock);
#endif
}
// When hide a main win, all main win which is covered by
// this hidding main win will be regenerated.
//
// Functions which lead to call this function:
// ShowWindow: hide a visible window with SW_HIDE parameters.
// DestroyWindow: destroy a visible window.
//
static void dskUpdateGCRInfoOnHideMainWin (MAINWIN* pWin)
{
RECT rcWin, rcTemp;
start_clip_window (pWin);
pWin->dwStyle &= ~WS_VISIBLE;
dskGetWindowRectInScreen (pWin, &rcWin);
recalc_windows_under_this (&sg_MainWinZOrder, pWin, &rcWin);
recalc_desktop (NULL);
end_clip_window (pWin);
IntersectRect (&rcTemp, &rcWin, &g_rcDesktop);
DesktopWinProc (HWND_DESKTOP, MSG_ERASEDESKTOP, 0, (LPARAM)(&rcTemp));
#if defined(_LITE_VERSION) && !defined(_STAND_ALONE)
if (mgIsServer)
scr_del_clip_rect (pWin->scr_idx);
#endif
}
// this is a top most window
static void dskUpdateGCRInfoOnHideMainWinEx(MAINWIN* pWin)
{
RECT rcWin, rcTemp;
start_clip_window (pWin);
pWin->dwStyle &= ~WS_VISIBLE;
dskGetWindowRectInScreen (pWin, &rcWin);
recalc_windows_under_this (&sg_TopMostWinZOrder, pWin, &rcWin);
recalc_windows (&sg_MainWinZOrder, &rcWin);
recalc_desktop (NULL);
end_clip_window (pWin);
IntersectRect (&rcTemp, &rcWin, &g_rcDesktop);
DesktopWinProc (HWND_DESKTOP, MSG_ERASEDESKTOP, 0, (LPARAM)(&rcTemp));
#if defined(_LITE_VERSION) && !defined(_STAND_ALONE)
if (mgIsServer)
scr_del_clip_rect (pWin->scr_idx);
#endif
}
static PMAINWIN dskGetFirstActivableWindow (void)
{
PZORDERNODE pNode;
PMAINWIN pTemp;
pNode = sg_MainWinZOrder.pTopMost;
while (pNode) {
pTemp = (PMAINWIN)(pNode->hWnd);
if ((pTemp->WinType != TYPE_CONTROL)
&& (pTemp->dwStyle & WS_VISIBLE)
&& !(pTemp->dwStyle & WS_DISABLED)
&& !(pTemp->dwExStyle & WS_EX_TOOLWINDOW))
return pTemp;
pNode = pNode->pNext;
}
pNode = sg_TopMostWinZOrder.pTopMost;
while (pNode) {
pTemp = (PMAINWIN)(pNode->hWnd);
if ((pTemp->WinType != TYPE_CONTROL)
&& (pTemp->dwStyle & WS_VISIBLE)
&& !(pTemp->dwStyle & WS_DISABLED)
&& !(pTemp->dwExStyle & WS_EX_TOOLWINDOW))
return pTemp;
pNode = pNode->pNext;
}
return NULL;
}
static PMAINWIN dskGetNextVisibleMainWindow (PMAINWIN pWin)
{
PZORDERNODE pNode;
PMAINWIN pTemp;
if (pWin)
pNode = pWin->pZOrderNode->pNext;
else
pNode = sg_MainWinZOrder.pTopMost;
while (pNode) {
pTemp = (PMAINWIN)(pNode->hWnd);
if ((pTemp->WinType != TYPE_CONTROL)
&& (pTemp->dwStyle & WS_VISIBLE)
&& !(pTemp->dwStyle & WS_DISABLED))
return pTemp;
pNode = pNode->pNext;
}
return NULL;
}
static PMAINWIN dskHideMainWindow (PMAINWIN pWin)
{
if (!(pWin->dwStyle & WS_VISIBLE))
return NULL;
// Update all affected windows' GCR info.
if (pWin->dwExStyle & WS_EX_TOPMOST)
dskUpdateGCRInfoOnHideMainWinEx (pWin);
else
dskUpdateGCRInfoOnHideMainWin (pWin);
// if this is the avtive window,
// must choose another window as the active one.
if (__mg_active_mainwnd == pWin)
dskChangActiveWindow (dskGetFirstActivableWindow ());
return __mg_active_mainwnd;
}
// When destroy a main win, all main win which is covered by
// this destroying main win will be redraw.
//
// Functions which lead to call this function:
// DestroyWindow: destroy a visible window.
//
// return: the new active window.
static PMAINWIN dskRemoveMainWindow (PMAINWIN pWin)
{
// Handle main window hosting.
if (pWin->pHosting)
dskRemoveHostedMainWindow (pWin->pHosting, pWin);
// Update all affected windows' GCR info.
if (pWin->dwStyle & WS_VISIBLE) {
if (pWin->dwExStyle & WS_EX_TOPMOST)
dskUpdateGCRInfoOnHideMainWinEx (pWin);
else
dskUpdateGCRInfoOnHideMainWin (pWin);
if (__mg_active_mainwnd == pWin)
dskChangActiveWindow (dskGetFirstActivableWindow ());
if (__mg_active_mainwnd == pWin)
__mg_active_mainwnd = NULL;
}
// Update window Z order list.
if (pWin->dwExStyle & WS_EX_TOPMOST)
remove_window (&sg_TopMostWinZOrder, pWin);
else
remove_window (&sg_MainWinZOrder, pWin);
return __mg_active_mainwnd;
}
static void dskUpdateAllGCRInfoOnShowMenu (RECT* prc)
{
clip_windows (&sg_TopMostWinZOrder, prc);
clip_windows (&sg_MainWinZOrder, prc);
clip_desktop (prc);
}
static void dskUpdateAllGCRInfoOnHideMenu (void)
{
PZORDERNODE pAffected;
RECT rcTemp;
PMAINWIN pTemp;
PTRACKMENUINFO ptmi;
pAffected = sg_TopMostWinZOrder.pTopMost;
while (pAffected){
pTemp = (PMAINWIN)(pAffected->hWnd);
if (pTemp->dwStyle & WS_VISIBLE) {
start_clip_window (pTemp);
dskGetWindowRectInScreen (pTemp, &rcTemp);
reset_window (pTemp, &rcTemp);
clip_by_all_above_this (&sg_TopMostWinZOrder, pTemp);
end_clip_window (pTemp);
ptmi = __mg_ptmi;
while (ptmi) {
SubtractClipRect (&pTemp->pGCRInfo->crgn, &ptmi->rc);
ptmi = ptmi->next;
}
}
pAffected = pAffected->pNext;
}
pAffected = sg_MainWinZOrder.pTopMost;
while (pAffected){
pTemp = (PMAINWIN)(pAffected->hWnd);
if (pTemp->dwStyle & WS_VISIBLE) {
start_clip_window (pTemp);
dskGetWindowRectInScreen (pTemp, &rcTemp);
reset_window (pTemp, &rcTemp);
clip_by_windows (&sg_TopMostWinZOrder, pTemp);
clip_by_all_above_this (&sg_MainWinZOrder, pTemp);
end_clip_window (pTemp);
ptmi = __mg_ptmi;
while (ptmi) {
SubtractClipRect (&pTemp->pGCRInfo->crgn, &ptmi->rc);
ptmi = ptmi->next;
}
}
pAffected = pAffected->pNext;
}
recalc_desktop (__mg_ptmi);
}
// 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;
if (__mg_ptmi) {
plast = __mg_ptmi;
while (plast->next) {
plast = plast->next;
}
plast->next = ptmi;
ptmi->prev = plast;
ptmi->next = NULL;
}
else {
__mg_ptmi = ptmi;
ptmi->next = NULL;
ptmi->prev = NULL;
}
#if defined(_LITE_VERSION) && !defined(_STAND_ALONE)
if (mgIsServer)
ptmi->scr_idx = scr_add_clip_rect (&ptmi->rc);
#endif
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, rcTemp;
if (__mg_ptmi == ptmi) {
__mg_ptmi = NULL;
}
else {
plast = __mg_ptmi;
while (plast->next) {
plast = plast->next;
}
plast->prev->next = NULL;
}
// Update all main windows' GCR info.
dskUpdateAllGCRInfoOnHideMenu ();
#if defined(_LITE_VERSION) && !defined(_STAND_ALONE)
if (mgIsServer)
scr_del_clip_rect (ptmi->scr_idx);
#endif
PopupMenuTrackProc (ptmi, MSG_HIDEMENU, 0, 0);
// Invalidate rect of affected main window.
pNode = sg_TopMostWinZOrder.pTopMost;
while (pNode) {
pTemp = (PMAINWIN)(pNode->hWnd);
if (pTemp->dwStyle & WS_VISIBLE) {
dskGetWindowRectInScreen (pTemp, &rcTemp);
if (IntersectRect (&rcInvalid, &ptmi->rc, &rcTemp)) {
dskScreenToClient (pTemp, &rcInvalid, &rcInvalid);
InvalidateRect ((HWND)pTemp, &rcInvalid, FALSE);
}
}
pNode = pNode->pNext;
}
pNode = sg_MainWinZOrder.pTopMost;
while (pNode) {
pTemp = (PMAINWIN)(pNode->hWnd);
pTemp = (PMAINWIN)(pNode->hWnd);
if (pTemp->dwStyle & WS_VISIBLE) {
dskGetWindowRectInScreen (pTemp, &rcTemp);
if (IntersectRect (&rcInvalid, &ptmi->rc, &rcTemp)) {
dskScreenToClient (pTemp, &rcInvalid, &rcInvalid);
InvalidateRect ((HWND)pTemp, &rcInvalid, FALSE);
}
}
pNode = pNode->pNext;
}
PopupMenuTrackProc (ptmi, MSG_ENDTRACKMENU, 0, 0);
return __mg_ptmi == ptmi;
}
static BOOL dskForceCloseMenu (void)
{
if (__mg_ptmi == NULL) return FALSE;
SendNotifyMessage (__mg_ptmi->hwnd, MSG_DEACTIVEMENU,
(WPARAM)__mg_ptmi->pmb, (LPARAM)__mg_ptmi->pmi);
PopupMenuTrackProc (__mg_ptmi, MSG_CLOSEMENU, 0, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -