/*
|
/*
|
* Copyright (c) 1999 Greg Haerr <greg@censoft.com>
|
* Copyright (c) 1999 Greg Haerr <greg@censoft.com>
|
*
|
*
|
* Win32 API upper level window creation, management and msg routines
|
* Win32 API upper level window creation, management and msg routines
|
*/
|
*/
|
#include "windows.h"
|
#include "windows.h"
|
#include "wintern.h"
|
#include "wintern.h"
|
#include "device.h"
|
#include "device.h"
|
#include <stdlib.h>
|
#include <stdlib.h>
|
#include <string.h>
|
#include <string.h>
|
|
|
#define PAINTONCE 1 /* =1 to queue paint msgs only once*/
|
#define PAINTONCE 1 /* =1 to queue paint msgs only once*/
|
#define MOUSETEST 1
|
#define MOUSETEST 1
|
|
|
MWLISTHEAD mwMsgHead; /* application msg queue*/
|
MWLISTHEAD mwMsgHead; /* application msg queue*/
|
MWLISTHEAD mwClassHead; /* register class list*/
|
MWLISTHEAD mwClassHead; /* register class list*/
|
|
|
int mwSYSMETRICS_CYCAPTION = 12; /* Y caption height*/
|
int mwSYSMETRICS_CYCAPTION = 12; /* Y caption height*/
|
int mwSYSMETRICS_CXFRAME = 3; /* width of frame border*/
|
int mwSYSMETRICS_CXFRAME = 3; /* width of frame border*/
|
int mwSYSMETRICS_CYFRAME = 3; /* height of frame border*/
|
int mwSYSMETRICS_CYFRAME = 3; /* height of frame border*/
|
int mwSYSMETRICS_CXBORDER = 1; /* width of single border*/
|
int mwSYSMETRICS_CXBORDER = 1; /* width of single border*/
|
int mwSYSMETRICS_CYBORDER = 1; /* width of single border*/
|
int mwSYSMETRICS_CYBORDER = 1; /* width of single border*/
|
int mwSYSMETRICS_CXVSCROLL = 13; /* width of vertical scrollbar*/
|
int mwSYSMETRICS_CXVSCROLL = 13; /* width of vertical scrollbar*/
|
int mwSYSMETRICS_CYHSCROLL = 13; /* height of horizontal scrollbar*/
|
int mwSYSMETRICS_CYHSCROLL = 13; /* height of horizontal scrollbar*/
|
int mwSYSMETRICS_CXHSCROLL = 13; /* width of arrow on horz scrollbar*/
|
int mwSYSMETRICS_CXHSCROLL = 13; /* width of arrow on horz scrollbar*/
|
int mwSYSMETRICS_CYVSCROLL = 13; /* height of arrow on vert scrollbar*/
|
int mwSYSMETRICS_CYVSCROLL = 13; /* height of arrow on vert scrollbar*/
|
int mwSYSMETRICS_CXDOUBLECLK = 2; /* +/- X double click position*/
|
int mwSYSMETRICS_CXDOUBLECLK = 2; /* +/- X double click position*/
|
int mwSYSMETRICS_CYDOUBLECLK = 2; /* +/- Y double click position*/
|
int mwSYSMETRICS_CYDOUBLECLK = 2; /* +/- Y double click position*/
|
int mwpaintSerial = 1; /* experimental alphablend sequencing*/
|
int mwpaintSerial = 1; /* experimental alphablend sequencing*/
|
int mwpaintNC = 1; /* experimental NC paint handling*/
|
int mwpaintNC = 1; /* experimental NC paint handling*/
|
BOOL mwforceNCpaint = FALSE; /* force NC paint when alpha blending*/
|
BOOL mwforceNCpaint = FALSE; /* force NC paint when alpha blending*/
|
|
|
static void MwOffsetChildren(HWND hwnd, int offx, int offy);
|
static void MwOffsetChildren(HWND hwnd, int offx, int offy);
|
|
|
LRESULT WINAPI
|
LRESULT WINAPI
|
CallWindowProc(WNDPROC lpPrevWndFunc, HWND hwnd, UINT Msg, WPARAM wParam,
|
CallWindowProc(WNDPROC lpPrevWndFunc, HWND hwnd, UINT Msg, WPARAM wParam,
|
LPARAM lParam)
|
LPARAM lParam)
|
{
|
{
|
return (*lpPrevWndFunc)(hwnd, Msg, wParam, lParam);
|
return (*lpPrevWndFunc)(hwnd, Msg, wParam, lParam);
|
}
|
}
|
|
|
LRESULT WINAPI
|
LRESULT WINAPI
|
SendMessage(HWND hwnd, UINT Msg,WPARAM wParam,LPARAM lParam)
|
SendMessage(HWND hwnd, UINT Msg,WPARAM wParam,LPARAM lParam)
|
{
|
{
|
if(hwnd && hwnd->pClass) {
|
if(hwnd && hwnd->pClass) {
|
hwnd->paintSerial = mwpaintSerial; /* assign msg sequence #*/
|
hwnd->paintSerial = mwpaintSerial; /* assign msg sequence #*/
|
return (*hwnd->pClass->lpfnWndProc)(hwnd, Msg, wParam, lParam);
|
return (*hwnd->pClass->lpfnWndProc)(hwnd, Msg, wParam, lParam);
|
}
|
}
|
return 0;
|
return 0;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
PostMessage(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
PostMessage(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
{
|
{
|
MSG * pMsg;
|
MSG * pMsg;
|
|
|
#if PAINTONCE
|
#if PAINTONCE
|
/* don't queue paint msgs, set window paint status instead*/
|
/* don't queue paint msgs, set window paint status instead*/
|
if(Msg == WM_PAINT) {
|
if(Msg == WM_PAINT) {
|
hwnd->gotPaintMsg = PAINT_NEEDSPAINT;
|
hwnd->gotPaintMsg = PAINT_NEEDSPAINT;
|
return TRUE;
|
return TRUE;
|
}
|
}
|
#endif
|
#endif
|
#if MOUSETEST
|
#if MOUSETEST
|
/* replace multiple mouse messages with one for better mouse handling*/
|
/* replace multiple mouse messages with one for better mouse handling*/
|
if(Msg == WM_MOUSEMOVE) {
|
if(Msg == WM_MOUSEMOVE) {
|
PMWLIST p;
|
PMWLIST p;
|
for(p=mwMsgHead.head; p; p=p->next) {
|
for(p=mwMsgHead.head; p; p=p->next) {
|
pMsg = GdItemAddr(p, MSG, link);
|
pMsg = GdItemAddr(p, MSG, link);
|
if(pMsg->hwnd == hwnd && pMsg->message == Msg) {
|
if(pMsg->hwnd == hwnd && pMsg->message == Msg) {
|
pMsg->wParam = wParam;
|
pMsg->wParam = wParam;
|
pMsg->lParam = lParam;
|
pMsg->lParam = lParam;
|
pMsg->time = GetTickCount();
|
pMsg->time = GetTickCount();
|
pMsg->pt.x = cursorx;
|
pMsg->pt.x = cursorx;
|
pMsg->pt.y = cursory;
|
pMsg->pt.y = cursory;
|
return TRUE;
|
return TRUE;
|
}
|
}
|
}
|
}
|
}
|
}
|
#endif
|
#endif
|
pMsg = GdItemNew(MSG);
|
pMsg = GdItemNew(MSG);
|
if(!pMsg)
|
if(!pMsg)
|
return FALSE;
|
return FALSE;
|
pMsg->hwnd = hwnd;
|
pMsg->hwnd = hwnd;
|
pMsg->message = Msg;
|
pMsg->message = Msg;
|
pMsg->wParam = wParam;
|
pMsg->wParam = wParam;
|
pMsg->lParam = lParam;
|
pMsg->lParam = lParam;
|
pMsg->time = GetTickCount();
|
pMsg->time = GetTickCount();
|
pMsg->pt.x = cursorx;
|
pMsg->pt.x = cursorx;
|
pMsg->pt.y = cursory;
|
pMsg->pt.y = cursory;
|
GdListAdd(&mwMsgHead, &pMsg->link);
|
GdListAdd(&mwMsgHead, &pMsg->link);
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
/* currently, we post to the single message queue, regardless of thread*/
|
/* currently, we post to the single message queue, regardless of thread*/
|
BOOL WINAPI
|
BOOL WINAPI
|
PostThreadMessage(DWORD dwThreadId, UINT Msg, WPARAM wParam, LPARAM lParam)
|
PostThreadMessage(DWORD dwThreadId, UINT Msg, WPARAM wParam, LPARAM lParam)
|
{
|
{
|
return PostMessage(NULL, Msg, wParam, lParam);
|
return PostMessage(NULL, Msg, wParam, lParam);
|
}
|
}
|
|
|
VOID WINAPI
|
VOID WINAPI
|
PostQuitMessage(int nExitCode)
|
PostQuitMessage(int nExitCode)
|
{
|
{
|
PostMessage(NULL, WM_QUIT, nExitCode, 0L);
|
PostMessage(NULL, WM_QUIT, nExitCode, 0L);
|
}
|
}
|
|
|
static BOOL
|
static BOOL
|
chkPaintMsg(HWND wp, LPMSG lpMsg)
|
chkPaintMsg(HWND wp, LPMSG lpMsg)
|
{
|
{
|
/*
|
/*
|
* Tricky: only repaint window if there
|
* Tricky: only repaint window if there
|
* isn't a mouse capture (window move) in progress,
|
* isn't a mouse capture (window move) in progress,
|
* or the window is the moving window.
|
* or the window is the moving window.
|
*/
|
*/
|
if(wp->gotPaintMsg == PAINT_NEEDSPAINT &&
|
if(wp->gotPaintMsg == PAINT_NEEDSPAINT &&
|
(!dragwp || dragwp == wp)) {
|
(!dragwp || dragwp == wp)) {
|
paint:
|
paint:
|
wp->gotPaintMsg = PAINT_PAINTED;
|
wp->gotPaintMsg = PAINT_PAINTED;
|
lpMsg->hwnd = wp;
|
lpMsg->hwnd = wp;
|
lpMsg->message = WM_PAINT;
|
lpMsg->message = WM_PAINT;
|
lpMsg->wParam = 0;
|
lpMsg->wParam = 0;
|
lpMsg->lParam = 0;
|
lpMsg->lParam = 0;
|
lpMsg->time = 0;
|
lpMsg->time = 0;
|
lpMsg->pt.x = cursorx;
|
lpMsg->pt.x = cursorx;
|
lpMsg->pt.y = cursory;
|
lpMsg->pt.y = cursory;
|
return TRUE;
|
return TRUE;
|
} else if(dragwp && wp->gotPaintMsg == PAINT_NEEDSPAINT) {
|
} else if(dragwp && wp->gotPaintMsg == PAINT_NEEDSPAINT) {
|
/* All other windows we'll check for
|
/* All other windows we'll check for
|
* event input first, then allow repaint.
|
* event input first, then allow repaint.
|
*/
|
*/
|
MwSelect();
|
MwSelect();
|
if(mwMsgHead.head == NULL)
|
if(mwMsgHead.head == NULL)
|
goto paint;
|
goto paint;
|
}
|
}
|
return FALSE;
|
return FALSE;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
PeekMessage(LPMSG lpMsg, HWND hwnd, UINT uMsgFilterMin, UINT uMsgFilterMax,
|
PeekMessage(LPMSG lpMsg, HWND hwnd, UINT uMsgFilterMin, UINT uMsgFilterMax,
|
UINT wRemoveMsg)
|
UINT wRemoveMsg)
|
{
|
{
|
HWND wp;
|
HWND wp;
|
PMSG pNxtMsg;
|
PMSG pNxtMsg;
|
|
|
/* check if no messages in queue*/
|
/* check if no messages in queue*/
|
if(mwMsgHead.head == NULL) {
|
if(mwMsgHead.head == NULL) {
|
#if PAINTONCE
|
#if PAINTONCE
|
/* check all windows for pending paint messages*/
|
/* check all windows for pending paint messages*/
|
for(wp=listwp; wp; wp=wp->next) {
|
for(wp=listwp; wp; wp=wp->next) {
|
if(!(wp->style & WS_CHILD)) {
|
if(!(wp->style & WS_CHILD)) {
|
if(chkPaintMsg(wp, lpMsg))
|
if(chkPaintMsg(wp, lpMsg))
|
return TRUE;
|
return TRUE;
|
}
|
}
|
}
|
}
|
for(wp=listwp; wp; wp=wp->next) {
|
for(wp=listwp; wp; wp=wp->next) {
|
if(wp->style & WS_CHILD) {
|
if(wp->style & WS_CHILD) {
|
if(chkPaintMsg(wp, lpMsg))
|
if(chkPaintMsg(wp, lpMsg))
|
return TRUE;
|
return TRUE;
|
}
|
}
|
}
|
}
|
#endif
|
#endif
|
MwSelect();
|
MwSelect();
|
}
|
}
|
|
|
if(mwMsgHead.head == NULL)
|
if(mwMsgHead.head == NULL)
|
return FALSE;
|
return FALSE;
|
|
|
pNxtMsg = (PMSG)mwMsgHead.head;
|
pNxtMsg = (PMSG)mwMsgHead.head;
|
if(wRemoveMsg & PM_REMOVE)
|
if(wRemoveMsg & PM_REMOVE)
|
GdListRemove(&mwMsgHead, &pNxtMsg->link);
|
GdListRemove(&mwMsgHead, &pNxtMsg->link);
|
*lpMsg = *pNxtMsg;
|
*lpMsg = *pNxtMsg;
|
if(wRemoveMsg & PM_REMOVE)
|
if(wRemoveMsg & PM_REMOVE)
|
GdItemFree(pNxtMsg);
|
GdItemFree(pNxtMsg);
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
GetMessage(LPMSG lpMsg,HWND hwnd,UINT wMsgFilterMin,UINT wMsgFilterMax)
|
GetMessage(LPMSG lpMsg,HWND hwnd,UINT wMsgFilterMin,UINT wMsgFilterMax)
|
{
|
{
|
/*
|
/*
|
* currently MwSelect() must poll for VT switch reasons,
|
* currently MwSelect() must poll for VT switch reasons,
|
* so this code will work
|
* so this code will work
|
*/
|
*/
|
while(!PeekMessage(lpMsg, hwnd, wMsgFilterMin, wMsgFilterMax,PM_REMOVE))
|
while(!PeekMessage(lpMsg, hwnd, wMsgFilterMin, wMsgFilterMax,PM_REMOVE))
|
continue;
|
continue;
|
return lpMsg->message != WM_QUIT;
|
return lpMsg->message != WM_QUIT;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
TranslateMessage(CONST MSG *lpMsg)
|
TranslateMessage(CONST MSG *lpMsg)
|
{
|
{
|
return FALSE;
|
return FALSE;
|
}
|
}
|
|
|
LONG WINAPI
|
LONG WINAPI
|
DispatchMessage(CONST MSG *lpMsg)
|
DispatchMessage(CONST MSG *lpMsg)
|
{
|
{
|
return SendMessage(lpMsg->hwnd, lpMsg->message, lpMsg->wParam,
|
return SendMessage(lpMsg->hwnd, lpMsg->message, lpMsg->wParam,
|
lpMsg->lParam);
|
lpMsg->lParam);
|
}
|
}
|
|
|
/* find the registered window class struct by name*/
|
/* find the registered window class struct by name*/
|
PWNDCLASS
|
PWNDCLASS
|
MwFindClassByName(LPCSTR lpClassName)
|
MwFindClassByName(LPCSTR lpClassName)
|
{
|
{
|
PMWLIST p;
|
PMWLIST p;
|
PWNDCLASS pClass;
|
PWNDCLASS pClass;
|
|
|
for(p=mwClassHead.head; p; p=p->next) {
|
for(p=mwClassHead.head; p; p=p->next) {
|
pClass = GdItemAddr(p, WNDCLASS, link);
|
pClass = GdItemAddr(p, WNDCLASS, link);
|
if(strcmpi(pClass->szClassName, lpClassName) == 0)
|
if(strcmpi(pClass->szClassName, lpClassName) == 0)
|
return pClass;
|
return pClass;
|
}
|
}
|
return NULL;
|
return NULL;
|
}
|
}
|
|
|
ATOM WINAPI
|
ATOM WINAPI
|
RegisterClass(CONST WNDCLASS *lpWndClass)
|
RegisterClass(CONST WNDCLASS *lpWndClass)
|
{
|
{
|
PWNDCLASS pClass;
|
PWNDCLASS pClass;
|
|
|
/* check if already present*/
|
/* check if already present*/
|
pClass = MwFindClassByName(lpWndClass->lpszClassName);
|
pClass = MwFindClassByName(lpWndClass->lpszClassName);
|
if(pClass)
|
if(pClass)
|
return 0;
|
return 0;
|
|
|
/* copy class into new struct*/
|
/* copy class into new struct*/
|
pClass = GdItemNew(WNDCLASS);
|
pClass = GdItemNew(WNDCLASS);
|
if(!pClass)
|
if(!pClass)
|
return 0;
|
return 0;
|
*pClass = *lpWndClass;
|
*pClass = *lpWndClass;
|
strcpy(pClass->szClassName, lpWndClass->lpszClassName);
|
strcpy(pClass->szClassName, lpWndClass->lpszClassName);
|
GdListAdd(&mwClassHead, &pClass->link);
|
GdListAdd(&mwClassHead, &pClass->link);
|
|
|
return 1;
|
return 1;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
UnregisterClass(LPCSTR lpClassName, HINSTANCE hInstance)
|
UnregisterClass(LPCSTR lpClassName, HINSTANCE hInstance)
|
{
|
{
|
PWNDCLASS pClass;
|
PWNDCLASS pClass;
|
|
|
pClass = MwFindClassByName(lpClassName);
|
pClass = MwFindClassByName(lpClassName);
|
if(!pClass)
|
if(!pClass)
|
return FALSE;
|
return FALSE;
|
GdListRemove(&mwClassHead, &pClass->link);
|
GdListRemove(&mwClassHead, &pClass->link);
|
DeleteObject(pClass->hbrBackground);
|
DeleteObject(pClass->hbrBackground);
|
GdItemFree(pClass);
|
GdItemFree(pClass);
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
HWND WINAPI
|
HWND WINAPI
|
CreateWindowEx(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName,
|
CreateWindowEx(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName,
|
DWORD dwStyle, int x, int y, int nWidth, int nHeight,
|
DWORD dwStyle, int x, int y, int nWidth, int nHeight,
|
HWND hwndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
|
HWND hwndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
|
{
|
{
|
HWND pwp; /* parent window */
|
HWND pwp; /* parent window */
|
HWND wp; /* new window */
|
HWND wp; /* new window */
|
HWND hwndOwner;
|
HWND hwndOwner;
|
PWNDCLASS pClass;
|
PWNDCLASS pClass;
|
CREATESTRUCT cs;
|
CREATESTRUCT cs;
|
static int nextx = 20;
|
static int nextx = 20;
|
static int nexty = 20;
|
static int nexty = 20;
|
|
|
pClass = MwFindClassByName(lpClassName);
|
pClass = MwFindClassByName(lpClassName);
|
if(!pClass)
|
if(!pClass)
|
return NULL;
|
return NULL;
|
|
|
if(x == CW_USEDEFAULT || y == CW_USEDEFAULT) {
|
if(x == CW_USEDEFAULT || y == CW_USEDEFAULT) {
|
x = nextx;
|
x = nextx;
|
nextx += 10;
|
nextx += 10;
|
y = nexty;
|
y = nexty;
|
nexty += 10;
|
nexty += 10;
|
if(nextx > 200)
|
if(nextx > 200)
|
nextx = nexty = 20;
|
nextx = nexty = 20;
|
}
|
}
|
if(nWidth == CW_USEDEFAULT || nHeight == CW_USEDEFAULT) {
|
if(nWidth == CW_USEDEFAULT || nHeight == CW_USEDEFAULT) {
|
nWidth = 250;
|
nWidth = 250;
|
nHeight = 250;
|
nHeight = 250;
|
}
|
}
|
|
|
if(hwndParent == NULL) {
|
if(hwndParent == NULL) {
|
if(dwStyle & WS_CHILD)
|
if(dwStyle & WS_CHILD)
|
return NULL;
|
return NULL;
|
pwp = rootwp;
|
pwp = rootwp;
|
} else
|
} else
|
pwp = hwndParent;
|
pwp = hwndParent;
|
|
|
/* WS_POPUP z-order parent is the root window (passed parent is owner)*/
|
/* WS_POPUP z-order parent is the root window (passed parent is owner)*/
|
if(dwStyle & WS_POPUP)
|
if(dwStyle & WS_POPUP)
|
pwp = rootwp; /* force clip to root, not z-parent*/
|
pwp = rootwp; /* force clip to root, not z-parent*/
|
|
|
/* window owner is NULL for child windows, else it's the passed parent*/
|
/* window owner is NULL for child windows, else it's the passed parent*/
|
if(dwStyle & WS_CHILD)
|
if(dwStyle & WS_CHILD)
|
hwndOwner = NULL;
|
hwndOwner = NULL;
|
else hwndOwner = hwndParent;
|
else hwndOwner = hwndParent;
|
|
|
wp = (HWND)GdItemAlloc(sizeof(struct hwnd) - 1 + pClass->cbWndExtra);
|
wp = (HWND)GdItemAlloc(sizeof(struct hwnd) - 1 + pClass->cbWndExtra);
|
if(!wp)
|
if(!wp)
|
return NULL;
|
return NULL;
|
|
|
/* force all clipping on by default*/
|
/* force all clipping on by default*/
|
dwStyle |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
|
dwStyle |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
|
|
|
wp->pClass = pClass;
|
wp->pClass = pClass;
|
wp->style = dwStyle;
|
wp->style = dwStyle;
|
wp->exstyle = dwExStyle;
|
wp->exstyle = dwExStyle;
|
wp->parent = pwp;
|
wp->parent = pwp;
|
wp->owner = hwndOwner;
|
wp->owner = hwndOwner;
|
wp->children = NULL;
|
wp->children = NULL;
|
wp->siblings = pwp->children;
|
wp->siblings = pwp->children;
|
pwp->children = wp;
|
pwp->children = wp;
|
wp->next = listwp;
|
wp->next = listwp;
|
listwp = wp;
|
listwp = wp;
|
wp->winrect.left = pwp->clirect.left + x;
|
wp->winrect.left = pwp->clirect.left + x;
|
wp->winrect.top = pwp->clirect.top + y;
|
wp->winrect.top = pwp->clirect.top + y;
|
wp->winrect.right = wp->winrect.left + nWidth;
|
wp->winrect.right = wp->winrect.left + nWidth;
|
wp->winrect.bottom = wp->winrect.top + nHeight;
|
wp->winrect.bottom = wp->winrect.top + nHeight;
|
wp->cursor = pwp->cursor;
|
wp->cursor = pwp->cursor;
|
wp->cursor->usecount++;
|
wp->cursor->usecount++;
|
wp->unmapcount = pwp->unmapcount + 1;
|
wp->unmapcount = pwp->unmapcount + 1;
|
wp->id = (int)hMenu;
|
wp->id = (int)hMenu;
|
wp->gotPaintMsg = PAINT_PAINTED;
|
wp->gotPaintMsg = PAINT_PAINTED;
|
strzcpy(wp->szTitle, lpWindowName, sizeof(wp->szTitle));
|
strzcpy(wp->szTitle, lpWindowName, sizeof(wp->szTitle));
|
#if UPDATEREGIONS
|
#if UPDATEREGIONS
|
wp->update = GdAllocRegion();
|
wp->update = GdAllocRegion();
|
#endif
|
#endif
|
wp->nextrabytes = pClass->cbWndExtra;
|
wp->nextrabytes = pClass->cbWndExtra;
|
|
|
/* calculate client area*/
|
/* calculate client area*/
|
MwCalcClientRect(wp);
|
MwCalcClientRect(wp);
|
|
|
cs.lpCreateParams = lpParam;
|
cs.lpCreateParams = lpParam;
|
cs.hInstance = hInstance;
|
cs.hInstance = hInstance;
|
cs.hMenu = hMenu;
|
cs.hMenu = hMenu;
|
cs.hwndParent = hwndParent;
|
cs.hwndParent = hwndParent;
|
cs.cy = nHeight;
|
cs.cy = nHeight;
|
cs.cx = nWidth;
|
cs.cx = nWidth;
|
cs.y = y;
|
cs.y = y;
|
cs.x = x;
|
cs.x = x;
|
cs.style = dwStyle;
|
cs.style = dwStyle;
|
cs.lpszName = lpWindowName;
|
cs.lpszName = lpWindowName;
|
cs.lpszClass = lpClassName;
|
cs.lpszClass = lpClassName;
|
cs.dwExStyle = dwExStyle;
|
cs.dwExStyle = dwExStyle;
|
|
|
if(SendMessage(wp, WM_CREATE, 0, (LPARAM)(LPSTR)&cs) == -1) {
|
if(SendMessage(wp, WM_CREATE, 0, (LPARAM)(LPSTR)&cs) == -1) {
|
MwDestroyWindow(wp, FALSE);
|
MwDestroyWindow(wp, FALSE);
|
return NULL;
|
return NULL;
|
}
|
}
|
|
|
/* send SIZE and MOVE msgs*/
|
/* send SIZE and MOVE msgs*/
|
MwSendSizeMove(wp, TRUE, TRUE);
|
MwSendSizeMove(wp, TRUE, TRUE);
|
|
|
if(wp->style & WS_VISIBLE) {
|
if(wp->style & WS_VISIBLE) {
|
MwShowWindow(wp, TRUE);
|
MwShowWindow(wp, TRUE);
|
SetFocus(wp);
|
SetFocus(wp);
|
}
|
}
|
|
|
return wp;
|
return wp;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
DestroyWindow(HWND hwnd)
|
DestroyWindow(HWND hwnd)
|
{
|
{
|
MwDestroyWindow(hwnd, TRUE);
|
MwDestroyWindow(hwnd, TRUE);
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
/*
|
/*
|
* Destroy the specified window, and all of its children.
|
* Destroy the specified window, and all of its children.
|
* This is a recursive routine.
|
* This is a recursive routine.
|
*/
|
*/
|
void
|
void
|
MwDestroyWindow(HWND hwnd,BOOL bSendMsg)
|
MwDestroyWindow(HWND hwnd,BOOL bSendMsg)
|
{
|
{
|
HWND wp = hwnd;
|
HWND wp = hwnd;
|
HWND prevwp;
|
HWND prevwp;
|
PMWLIST p;
|
PMWLIST p;
|
PMSG pmsg;
|
PMSG pmsg;
|
|
|
if (wp == rootwp)
|
if (wp == rootwp)
|
return;
|
return;
|
|
|
/*
|
/*
|
* Unmap the window.
|
* Unmap the window.
|
*/
|
*/
|
if (wp->unmapcount == 0)
|
if (wp->unmapcount == 0)
|
MwHideWindow(wp, FALSE, FALSE);
|
MwHideWindow(wp, FALSE, FALSE);
|
|
|
if(bSendMsg)
|
if(bSendMsg)
|
SendMessage(hwnd, WM_DESTROY, 0, 0L);
|
SendMessage(hwnd, WM_DESTROY, 0, 0L);
|
|
|
/*
|
/*
|
* Disable all sendmessages to this window.
|
* Disable all sendmessages to this window.
|
*/
|
*/
|
wp->pClass = NULL;
|
wp->pClass = NULL;
|
|
|
/*
|
/*
|
* Destroy all children, sending WM_DESTROY messages.
|
* Destroy all children, sending WM_DESTROY messages.
|
*/
|
*/
|
while (wp->children)
|
while (wp->children)
|
MwDestroyWindow(wp->children, bSendMsg);
|
MwDestroyWindow(wp->children, bSendMsg);
|
|
|
/*
|
/*
|
* Free any cursor associated with the window.
|
* Free any cursor associated with the window.
|
*/
|
*/
|
if (wp->cursor->usecount-- == 1) {
|
if (wp->cursor->usecount-- == 1) {
|
free(wp->cursor);
|
free(wp->cursor);
|
wp->cursor = NULL;
|
wp->cursor = NULL;
|
}
|
}
|
|
|
/*
|
/*
|
* Remove this window from the child list of its parent.
|
* Remove this window from the child list of its parent.
|
*/
|
*/
|
prevwp = wp->parent->children;
|
prevwp = wp->parent->children;
|
if (prevwp == wp)
|
if (prevwp == wp)
|
wp->parent->children = wp->siblings;
|
wp->parent->children = wp->siblings;
|
else {
|
else {
|
while (prevwp->siblings != wp)
|
while (prevwp->siblings != wp)
|
prevwp = prevwp->siblings;
|
prevwp = prevwp->siblings;
|
prevwp->siblings = wp->siblings;
|
prevwp->siblings = wp->siblings;
|
}
|
}
|
wp->siblings = NULL;
|
wp->siblings = NULL;
|
|
|
/*
|
/*
|
* Remove this window from the complete list of windows.
|
* Remove this window from the complete list of windows.
|
*/
|
*/
|
prevwp = listwp;
|
prevwp = listwp;
|
if (prevwp == wp)
|
if (prevwp == wp)
|
listwp = wp->next;
|
listwp = wp->next;
|
else {
|
else {
|
while (prevwp->next != wp)
|
while (prevwp->next != wp)
|
prevwp = prevwp->next;
|
prevwp = prevwp->next;
|
prevwp->next = wp->next;
|
prevwp->next = wp->next;
|
}
|
}
|
wp->next = NULL;
|
wp->next = NULL;
|
|
|
/*
|
/*
|
* Forget various information related to this window.
|
* Forget various information related to this window.
|
* Then finally free the structure.
|
* Then finally free the structure.
|
*/
|
*/
|
|
|
/* Remove all messages from msg queue for this window*/
|
/* Remove all messages from msg queue for this window*/
|
for(p=mwMsgHead.head; p; ) {
|
for(p=mwMsgHead.head; p; ) {
|
pmsg = GdItemAddr(p, MSG, link);
|
pmsg = GdItemAddr(p, MSG, link);
|
if(pmsg->hwnd == wp) {
|
if(pmsg->hwnd == wp) {
|
p = p->next;
|
p = p->next;
|
GdListRemove(&mwMsgHead, &pmsg->link);
|
GdListRemove(&mwMsgHead, &pmsg->link);
|
GdItemFree(p);
|
GdItemFree(p);
|
} else
|
} else
|
p = p->next;
|
p = p->next;
|
}
|
}
|
|
|
/* FIXME: destroy hdc's relating to window?*/
|
/* FIXME: destroy hdc's relating to window?*/
|
|
|
if (wp == capturewp) {
|
if (wp == capturewp) {
|
capturewp = NULL;
|
capturewp = NULL;
|
MwCheckMouseWindow();
|
MwCheckMouseWindow();
|
}
|
}
|
|
|
if (wp == MwGetTopWindow(focuswp))
|
if (wp == MwGetTopWindow(focuswp))
|
SetFocus(rootwp->children? rootwp->children: rootwp);
|
SetFocus(rootwp->children? rootwp->children: rootwp);
|
|
|
/* destroy private DC*/
|
/* destroy private DC*/
|
if(wp->owndc) {
|
if(wp->owndc) {
|
HDC hdc = wp->owndc;
|
HDC hdc = wp->owndc;
|
wp->owndc = NULL; /* force destroy with ReleaseDC*/
|
wp->owndc = NULL; /* force destroy with ReleaseDC*/
|
ReleaseDC(wp, hdc);
|
ReleaseDC(wp, hdc);
|
}
|
}
|
#if UPDATEREGIONS
|
#if UPDATEREGIONS
|
GdDestroyRegion(wp->update);
|
GdDestroyRegion(wp->update);
|
#endif
|
#endif
|
GdItemFree(wp);
|
GdItemFree(wp);
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
IsWindow(HWND hwnd)
|
IsWindow(HWND hwnd)
|
{
|
{
|
HWND wp;
|
HWND wp;
|
|
|
for(wp=listwp; wp; wp=wp->next)
|
for(wp=listwp; wp; wp=wp->next)
|
if(wp == hwnd)
|
if(wp == hwnd)
|
return TRUE;
|
return TRUE;
|
return FALSE;
|
return FALSE;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
ShowWindow(HWND hwnd, int nCmdShow)
|
ShowWindow(HWND hwnd, int nCmdShow)
|
{
|
{
|
if(!hwnd)
|
if(!hwnd)
|
return FALSE;
|
return FALSE;
|
|
|
/* fix: send show msg*/
|
/* fix: send show msg*/
|
|
|
switch(nCmdShow) {
|
switch(nCmdShow) {
|
case SW_HIDE:
|
case SW_HIDE:
|
if (!(hwnd->style & WS_VISIBLE))
|
if (!(hwnd->style & WS_VISIBLE))
|
return FALSE;
|
return FALSE;
|
MwHideWindow(hwnd, TRUE, TRUE);
|
MwHideWindow(hwnd, TRUE, TRUE);
|
hwnd->style &= ~WS_VISIBLE;
|
hwnd->style &= ~WS_VISIBLE;
|
break;
|
break;
|
|
|
default:
|
default:
|
if (hwnd->style & WS_VISIBLE)
|
if (hwnd->style & WS_VISIBLE)
|
return FALSE;
|
return FALSE;
|
hwnd->style |= WS_VISIBLE;
|
hwnd->style |= WS_VISIBLE;
|
MwShowWindow(hwnd, TRUE);
|
MwShowWindow(hwnd, TRUE);
|
}
|
}
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
InvalidateRect(HWND hwnd, CONST RECT *lpRect, BOOL bErase)
|
InvalidateRect(HWND hwnd, CONST RECT *lpRect, BOOL bErase)
|
{
|
{
|
/* FIXME: handle bErase*/
|
/* FIXME: handle bErase*/
|
if(!hwnd)
|
if(!hwnd)
|
MwRedrawScreen();
|
MwRedrawScreen();
|
else {
|
else {
|
#if UPDATEREGIONS
|
#if UPDATEREGIONS
|
RECT rc;
|
RECT rc;
|
|
|
/* add to update region*/
|
/* add to update region*/
|
if(!lpRect)
|
if(!lpRect)
|
GetClientRect(hwnd, &rc);
|
GetClientRect(hwnd, &rc);
|
else rc = *lpRect;
|
else rc = *lpRect;
|
rc.bottom += mwSYSMETRICS_CYCAPTION +
|
rc.bottom += mwSYSMETRICS_CYCAPTION +
|
mwSYSMETRICS_CYFRAME + 1;
|
mwSYSMETRICS_CYFRAME + 1;
|
rc.right += mwSYSMETRICS_CXFRAME;
|
rc.right += mwSYSMETRICS_CXFRAME;
|
MwUnionUpdateRegion(hwnd, rc.left, rc.top,
|
MwUnionUpdateRegion(hwnd, rc.left, rc.top,
|
rc.right-rc.left, rc.bottom-rc.top, TRUE);
|
rc.right-rc.left, rc.bottom-rc.top, TRUE);
|
|
|
/* if update region not empty, mark as needing painting*/
|
/* if update region not empty, mark as needing painting*/
|
if(hwnd->update->numRects != 0)
|
if(hwnd->update->numRects != 0)
|
#endif
|
#endif
|
if(hwnd->gotPaintMsg == PAINT_PAINTED)
|
if(hwnd->gotPaintMsg == PAINT_PAINTED)
|
hwnd->gotPaintMsg = PAINT_NEEDSPAINT;
|
hwnd->gotPaintMsg = PAINT_NEEDSPAINT;
|
}
|
}
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
#if UPDATEREGIONS
|
#if UPDATEREGIONS
|
/* add region to window update region*/
|
/* add region to window update region*/
|
BOOL WINAPI
|
BOOL WINAPI
|
InvalidateRgn(HWND hwnd, HRGN hrgn, BOOL bErase)
|
InvalidateRgn(HWND hwnd, HRGN hrgn, BOOL bErase)
|
{
|
{
|
/* FIXME: handle bErase*/
|
/* FIXME: handle bErase*/
|
if(hwnd) {
|
if(hwnd) {
|
if(!hrgn)
|
if(!hrgn)
|
/* add client area to update region*/
|
/* add client area to update region*/
|
return InvalidateRect(hwnd, NULL, bErase);
|
return InvalidateRect(hwnd, NULL, bErase);
|
|
|
/* passed region is in client coords, convert to screen*/
|
/* passed region is in client coords, convert to screen*/
|
GdOffsetRegion(((MWRGNOBJ *)hrgn)->rgn,
|
GdOffsetRegion(((MWRGNOBJ *)hrgn)->rgn,
|
hwnd->clirect.left, hwnd->clirect.top);
|
hwnd->clirect.left, hwnd->clirect.top);
|
GdUnionRegion(hwnd->update, hwnd->update,
|
GdUnionRegion(hwnd->update, hwnd->update,
|
((MWRGNOBJ *)hrgn)->rgn);
|
((MWRGNOBJ *)hrgn)->rgn);
|
GdOffsetRegion(((MWRGNOBJ *)hrgn)->rgn,
|
GdOffsetRegion(((MWRGNOBJ *)hrgn)->rgn,
|
-hwnd->clirect.left, -hwnd->clirect.top);
|
-hwnd->clirect.left, -hwnd->clirect.top);
|
|
|
/* if update region not empty, mark as needing painting*/
|
/* if update region not empty, mark as needing painting*/
|
if(hwnd->update->numRects != 0)
|
if(hwnd->update->numRects != 0)
|
if(hwnd->gotPaintMsg == PAINT_PAINTED)
|
if(hwnd->gotPaintMsg == PAINT_PAINTED)
|
hwnd->gotPaintMsg = PAINT_NEEDSPAINT;
|
hwnd->gotPaintMsg = PAINT_NEEDSPAINT;
|
}
|
}
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
ValidateRect(HWND hwnd, CONST RECT *lprc)
|
ValidateRect(HWND hwnd, CONST RECT *lprc)
|
{
|
{
|
RECT rc;
|
RECT rc;
|
|
|
if(!hwnd)
|
if(!hwnd)
|
MwRedrawScreen();
|
MwRedrawScreen();
|
else {
|
else {
|
/* subtract from update region*/
|
/* subtract from update region*/
|
if(!lprc)
|
if(!lprc)
|
GetClientRect(hwnd, &rc);
|
GetClientRect(hwnd, &rc);
|
else rc = *lprc;
|
else rc = *lprc;
|
rc.bottom += mwSYSMETRICS_CYCAPTION +
|
rc.bottom += mwSYSMETRICS_CYCAPTION +
|
mwSYSMETRICS_CYFRAME + 1;
|
mwSYSMETRICS_CYFRAME + 1;
|
rc.right += mwSYSMETRICS_CXFRAME;
|
rc.right += mwSYSMETRICS_CXFRAME;
|
MwUnionUpdateRegion(hwnd, rc.left, rc.top,
|
MwUnionUpdateRegion(hwnd, rc.left, rc.top,
|
rc.right-rc.left, rc.bottom-rc.top, FALSE);
|
rc.right-rc.left, rc.bottom-rc.top, FALSE);
|
|
|
/* if update region empty, mark window as painted*/
|
/* if update region empty, mark window as painted*/
|
if(hwnd->update->numRects == 0)
|
if(hwnd->update->numRects == 0)
|
if(hwnd->gotPaintMsg == PAINT_NEEDSPAINT)
|
if(hwnd->gotPaintMsg == PAINT_NEEDSPAINT)
|
hwnd->gotPaintMsg = PAINT_PAINTED;
|
hwnd->gotPaintMsg = PAINT_PAINTED;
|
}
|
}
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
/* remove region from window update region*/
|
/* remove region from window update region*/
|
BOOL WINAPI
|
BOOL WINAPI
|
ValidateRgn(HWND hwnd, HRGN hrgn)
|
ValidateRgn(HWND hwnd, HRGN hrgn)
|
{
|
{
|
if(hwnd) {
|
if(hwnd) {
|
if(!hrgn)
|
if(!hrgn)
|
/* remove client area from update region*/
|
/* remove client area from update region*/
|
return ValidateRect(hwnd, NULL);
|
return ValidateRect(hwnd, NULL);
|
|
|
/* passed region is in client coords, convert to screen*/
|
/* passed region is in client coords, convert to screen*/
|
GdOffsetRegion(((MWRGNOBJ *)hrgn)->rgn,
|
GdOffsetRegion(((MWRGNOBJ *)hrgn)->rgn,
|
hwnd->clirect.left, hwnd->clirect.top);
|
hwnd->clirect.left, hwnd->clirect.top);
|
GdSubtractRegion(hwnd->update, hwnd->update,
|
GdSubtractRegion(hwnd->update, hwnd->update,
|
((MWRGNOBJ *)hrgn)->rgn);
|
((MWRGNOBJ *)hrgn)->rgn);
|
GdOffsetRegion(((MWRGNOBJ *)hrgn)->rgn,
|
GdOffsetRegion(((MWRGNOBJ *)hrgn)->rgn,
|
-hwnd->clirect.left, -hwnd->clirect.top);
|
-hwnd->clirect.left, -hwnd->clirect.top);
|
|
|
/* if update region empty, mark window as painted*/
|
/* if update region empty, mark window as painted*/
|
if(hwnd->update->numRects == 0)
|
if(hwnd->update->numRects == 0)
|
if(hwnd->gotPaintMsg == PAINT_NEEDSPAINT)
|
if(hwnd->gotPaintMsg == PAINT_NEEDSPAINT)
|
hwnd->gotPaintMsg = PAINT_PAINTED;
|
hwnd->gotPaintMsg = PAINT_PAINTED;
|
}
|
}
|
return TRUE;
|
return TRUE;
|
}
|
}
|
#endif /* UPDATEREGIONS*/
|
#endif /* UPDATEREGIONS*/
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
UpdateWindow(HWND hwnd)
|
UpdateWindow(HWND hwnd)
|
{
|
{
|
#if PAINTONCE
|
#if PAINTONCE
|
if(hwnd && hwnd->gotPaintMsg == PAINT_NEEDSPAINT) {
|
if(hwnd && hwnd->gotPaintMsg == PAINT_NEEDSPAINT) {
|
SendMessage(hwnd, WM_PAINT, 0, 0L);
|
SendMessage(hwnd, WM_PAINT, 0, 0L);
|
hwnd->gotPaintMsg = PAINT_PAINTED;
|
hwnd->gotPaintMsg = PAINT_PAINTED;
|
return TRUE;
|
return TRUE;
|
}
|
}
|
return FALSE;
|
return FALSE;
|
#else
|
#else
|
/* fix: remove other paint messages from queue*/
|
/* fix: remove other paint messages from queue*/
|
SendMessage(hwnd, WM_PAINT, 0, 0L);
|
SendMessage(hwnd, WM_PAINT, 0, 0L);
|
return TRUE;
|
return TRUE;
|
#endif
|
#endif
|
}
|
}
|
|
|
HWND WINAPI
|
HWND WINAPI
|
GetFocus(VOID)
|
GetFocus(VOID)
|
{
|
{
|
return focuswp;
|
return focuswp;
|
}
|
}
|
|
|
HWND WINAPI
|
HWND WINAPI
|
SetFocus(HWND hwnd)
|
SetFocus(HWND hwnd)
|
{
|
{
|
HWND oldfocus;
|
HWND oldfocus;
|
HWND top, top2;
|
HWND top, top2;
|
|
|
/* if NULL or hidden, set focus to desktop*/
|
/* if NULL or hidden, set focus to desktop*/
|
if(!hwnd || hwnd->unmapcount)
|
if(!hwnd || hwnd->unmapcount)
|
hwnd = rootwp;
|
hwnd = rootwp;
|
|
|
if(hwnd == focuswp)
|
if(hwnd == focuswp)
|
return focuswp;
|
return focuswp;
|
|
|
oldfocus = focuswp;
|
oldfocus = focuswp;
|
SendMessage(oldfocus, WM_KILLFOCUS, (WPARAM)hwnd, 0L);
|
SendMessage(oldfocus, WM_KILLFOCUS, (WPARAM)hwnd, 0L);
|
focuswp = hwnd;
|
focuswp = hwnd;
|
SendMessage(focuswp, WM_SETFOCUS, (WPARAM)oldfocus, 0L);
|
SendMessage(focuswp, WM_SETFOCUS, (WPARAM)oldfocus, 0L);
|
|
|
/* FIXME SetActiveWindow() here?*/
|
/* FIXME SetActiveWindow() here?*/
|
top = MwGetTopWindow(oldfocus);
|
top = MwGetTopWindow(oldfocus);
|
top2 = MwGetTopWindow(focuswp);
|
top2 = MwGetTopWindow(focuswp);
|
if(top2 != top) {
|
if(top2 != top) {
|
/* send deactivate*/
|
/* send deactivate*/
|
SendMessage(top, WM_ACTIVATE, (WPARAM)MAKELONG(WA_INACTIVE, 0),
|
SendMessage(top, WM_ACTIVATE, (WPARAM)MAKELONG(WA_INACTIVE, 0),
|
(LPARAM)top2);
|
(LPARAM)top2);
|
/* repaint captions*/
|
/* repaint captions*/
|
MwPaintNCArea(top);
|
MwPaintNCArea(top);
|
#if 0
|
#if 0
|
/* Make sure that caption area is fully invalidated,
|
/* Make sure that caption area is fully invalidated,
|
* as repaint will be in active color.
|
* as repaint will be in active color.
|
* FIXME: this doesn't work; breaks terminal emulator
|
* FIXME: this doesn't work; breaks terminal emulator
|
* on focus out/in
|
* on focus out/in
|
*/
|
*/
|
MwUnionUpdateRegion(top2, 0, 0,
|
MwUnionUpdateRegion(top2, 0, 0,
|
top2->winrect.right-top2->winrect.left,
|
top2->winrect.right-top2->winrect.left,
|
mwSYSMETRICS_CYCAPTION+4, TRUE);
|
mwSYSMETRICS_CYCAPTION+4, TRUE);
|
#endif
|
#endif
|
/* send deactivate*/
|
/* send deactivate*/
|
SendMessage(top, WM_ACTIVATE, (WPARAM)MAKELONG(WA_ACTIVE, 0),
|
SendMessage(top, WM_ACTIVATE, (WPARAM)MAKELONG(WA_ACTIVE, 0),
|
(LPARAM)top);
|
(LPARAM)top);
|
MwPaintNCArea(top2);
|
MwPaintNCArea(top2);
|
}
|
}
|
|
|
return oldfocus;
|
return oldfocus;
|
}
|
}
|
|
|
/* the foreground window is the top level window at the top of the z order*/
|
/* the foreground window is the top level window at the top of the z order*/
|
/* setting the foreground window sets focus and moves window to top*/
|
/* setting the foreground window sets focus and moves window to top*/
|
BOOL WINAPI
|
BOOL WINAPI
|
SetForegroundWindow(HWND hwnd)
|
SetForegroundWindow(HWND hwnd)
|
{
|
{
|
/* activate (set focus to) specified window*/
|
/* activate (set focus to) specified window*/
|
SetFocus(hwnd);
|
SetFocus(hwnd);
|
|
|
/* raise top level parent to top of z order*/
|
/* raise top level parent to top of z order*/
|
SetWindowPos(MwGetTopWindow(hwnd), HWND_TOP, 0, 0, 0, 0,
|
SetWindowPos(MwGetTopWindow(hwnd), HWND_TOP, 0, 0, 0, 0,
|
SWP_NOMOVE|SWP_NOSIZE);
|
SWP_NOMOVE|SWP_NOSIZE);
|
|
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
/* our SetActiveWindow is the same as SetFocus, no z order change*/
|
/* our SetActiveWindow is the same as SetFocus, no z order change*/
|
HWND WINAPI
|
HWND WINAPI
|
SetActiveWindow(HWND hwnd)
|
SetActiveWindow(HWND hwnd)
|
{
|
{
|
HWND oldActive;
|
HWND oldActive;
|
|
|
oldActive = GetActiveWindow();
|
oldActive = GetActiveWindow();
|
SetFocus(hwnd); /* WM_ACTIVATE sent by SetFocus*/
|
SetFocus(hwnd); /* WM_ACTIVATE sent by SetFocus*/
|
return oldActive;
|
return oldActive;
|
}
|
}
|
|
|
/* The active window is the first non-child ancestor of focus window*/
|
/* The active window is the first non-child ancestor of focus window*/
|
HWND WINAPI
|
HWND WINAPI
|
GetActiveWindow(VOID)
|
GetActiveWindow(VOID)
|
{
|
{
|
return MwGetTopWindow(focuswp);
|
return MwGetTopWindow(focuswp);
|
}
|
}
|
|
|
/* activate the top level window associated with window*/
|
/* activate the top level window associated with window*/
|
BOOL WINAPI
|
BOOL WINAPI
|
BringWindowToTop(HWND hwnd)
|
BringWindowToTop(HWND hwnd)
|
{
|
{
|
return SetForegroundWindow(hwnd);
|
return SetForegroundWindow(hwnd);
|
}
|
}
|
|
|
HWND WINAPI
|
HWND WINAPI
|
GetDesktopWindow(VOID)
|
GetDesktopWindow(VOID)
|
{
|
{
|
return rootwp;
|
return rootwp;
|
}
|
}
|
|
|
HWND
|
HWND
|
MwGetTopWindow(HWND hwnd)
|
MwGetTopWindow(HWND hwnd)
|
{
|
{
|
while(hwnd->style & WS_CHILD)
|
while(hwnd->style & WS_CHILD)
|
hwnd = hwnd->parent;
|
hwnd = hwnd->parent;
|
return hwnd;
|
return hwnd;
|
}
|
}
|
|
|
HWND WINAPI
|
HWND WINAPI
|
GetParent(HWND hwnd)
|
GetParent(HWND hwnd)
|
{
|
{
|
/* top level windows return NULL instead of rootwp*/
|
/* top level windows return NULL instead of rootwp*/
|
if(!hwnd || !(hwnd->style & (WS_POPUP|WS_CHILD)))
|
if(!hwnd || !(hwnd->style & (WS_POPUP|WS_CHILD)))
|
return NULL; /* toplevel window*/
|
return NULL; /* toplevel window*/
|
if(hwnd->style & WS_POPUP)
|
if(hwnd->style & WS_POPUP)
|
return hwnd->owner; /* popup window*/
|
return hwnd->owner; /* popup window*/
|
return hwnd->parent; /* child window*/
|
return hwnd->parent; /* child window*/
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
EnableWindow(HWND hwnd, BOOL bEnable)
|
EnableWindow(HWND hwnd, BOOL bEnable)
|
{
|
{
|
if(bEnable && (hwnd->style & WS_DISABLED)) {
|
if(bEnable && (hwnd->style & WS_DISABLED)) {
|
/* enable window*/
|
/* enable window*/
|
hwnd->style &= ~WS_DISABLED;
|
hwnd->style &= ~WS_DISABLED;
|
SendMessage(hwnd, WM_ENABLE, TRUE, 0L);
|
SendMessage(hwnd, WM_ENABLE, TRUE, 0L);
|
return TRUE;
|
return TRUE;
|
}
|
}
|
if(!bEnable && !(hwnd->style & WS_DISABLED)) {
|
if(!bEnable && !(hwnd->style & WS_DISABLED)) {
|
/* disable window*/
|
/* disable window*/
|
hwnd->style |= WS_DISABLED;
|
hwnd->style |= WS_DISABLED;
|
/* FIXME: handle lost focus for child window of hwnd*/
|
/* FIXME: handle lost focus for child window of hwnd*/
|
/* FIXME: handle lost focus for capture window*/
|
/* FIXME: handle lost focus for capture window*/
|
if(hwnd == focuswp)
|
if(hwnd == focuswp)
|
SetFocus(NULL);
|
SetFocus(NULL);
|
SendMessage(hwnd, WM_ENABLE, FALSE, 0L);
|
SendMessage(hwnd, WM_ENABLE, FALSE, 0L);
|
return FALSE;
|
return FALSE;
|
}
|
}
|
return (hwnd->style & WS_DISABLED) != 0;
|
return (hwnd->style & WS_DISABLED) != 0;
|
}
|
}
|
|
|
/* calc window rect from client rect in screen coords*/
|
/* calc window rect from client rect in screen coords*/
|
BOOL WINAPI
|
BOOL WINAPI
|
AdjustWindowRectEx(LPRECT lpRect, DWORD dwStyle, BOOL bMenu, DWORD dwExStyle)
|
AdjustWindowRectEx(LPRECT lpRect, DWORD dwStyle, BOOL bMenu, DWORD dwExStyle)
|
{
|
{
|
int yoffset;
|
int yoffset;
|
|
|
if(dwStyle & WS_BORDER) {
|
if(dwStyle & WS_BORDER) {
|
if((dwStyle & WS_CAPTION) == WS_CAPTION) {
|
if((dwStyle & WS_CAPTION) == WS_CAPTION) {
|
InflateRect(lpRect, mwSYSMETRICS_CXFRAME,
|
InflateRect(lpRect, mwSYSMETRICS_CXFRAME,
|
mwSYSMETRICS_CYFRAME);
|
mwSYSMETRICS_CYFRAME);
|
yoffset = mwSYSMETRICS_CYCAPTION + 1;
|
yoffset = mwSYSMETRICS_CYCAPTION + 1;
|
lpRect->top -= yoffset;
|
lpRect->top -= yoffset;
|
lpRect->bottom -= yoffset;
|
lpRect->bottom -= yoffset;
|
} else
|
} else
|
InflateRect(lpRect, 1, 1);
|
InflateRect(lpRect, 1, 1);
|
|
|
/* make sure upper left is on screen*/
|
/* make sure upper left is on screen*/
|
if(lpRect->left < 0) {
|
if(lpRect->left < 0) {
|
lpRect->right -= lpRect->left;
|
lpRect->right -= lpRect->left;
|
lpRect->left = 0;
|
lpRect->left = 0;
|
}
|
}
|
if(lpRect->top < 0) {
|
if(lpRect->top < 0) {
|
lpRect->bottom -= lpRect->top;
|
lpRect->bottom -= lpRect->top;
|
lpRect->top = 0;
|
lpRect->top = 0;
|
}
|
}
|
}
|
}
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
/* set the client rect for a window from the window position*/
|
/* set the client rect for a window from the window position*/
|
void
|
void
|
MwCalcClientRect(HWND hwnd)
|
MwCalcClientRect(HWND hwnd)
|
{
|
{
|
NCCALCSIZE_PARAMS nccs;
|
NCCALCSIZE_PARAMS nccs;
|
|
|
/* set first rectangle to window rect*/
|
/* set first rectangle to window rect*/
|
nccs.rgrc[0] = hwnd->winrect;
|
nccs.rgrc[0] = hwnd->winrect;
|
SendMessage(hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)(LPSTR)&nccs);
|
SendMessage(hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)(LPSTR)&nccs);
|
hwnd->clirect = nccs.rgrc[0];
|
hwnd->clirect = nccs.rgrc[0];
|
|
|
/* adjust client area if scrollbar(s) visible*/
|
/* adjust client area if scrollbar(s) visible*/
|
MwAdjustNCScrollbars(hwnd);
|
MwAdjustNCScrollbars(hwnd);
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
GetClientRect(HWND hwnd, LPRECT lpRect)
|
GetClientRect(HWND hwnd, LPRECT lpRect)
|
{
|
{
|
if(!hwnd || !lpRect)
|
if(!hwnd || !lpRect)
|
return FALSE;
|
return FALSE;
|
|
|
/* convert client area rect from screen coordinates*/
|
/* convert client area rect from screen coordinates*/
|
lpRect->left = 0;
|
lpRect->left = 0;
|
lpRect->top = 0;
|
lpRect->top = 0;
|
lpRect->right = hwnd->clirect.right - hwnd->clirect.left;
|
lpRect->right = hwnd->clirect.right - hwnd->clirect.left;
|
lpRect->bottom = hwnd->clirect.bottom - hwnd->clirect.top;
|
lpRect->bottom = hwnd->clirect.bottom - hwnd->clirect.top;
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
GetWindowRect(HWND hwnd, LPRECT lpRect)
|
GetWindowRect(HWND hwnd, LPRECT lpRect)
|
{
|
{
|
if(!hwnd || !lpRect)
|
if(!hwnd || !lpRect)
|
return FALSE;
|
return FALSE;
|
|
|
/* window rect is already in screen coordinates*/
|
/* window rect is already in screen coordinates*/
|
*lpRect = hwnd->winrect;
|
*lpRect = hwnd->winrect;
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
ClientToScreen(HWND hwnd, LPPOINT lpPoint)
|
ClientToScreen(HWND hwnd, LPPOINT lpPoint)
|
{
|
{
|
if(!hwnd || !lpPoint)
|
if(!hwnd || !lpPoint)
|
return FALSE;
|
return FALSE;
|
MapWindowPoints(hwnd, NULL, lpPoint, 1);
|
MapWindowPoints(hwnd, NULL, lpPoint, 1);
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
ScreenToClient(HWND hwnd, LPPOINT lpPoint)
|
ScreenToClient(HWND hwnd, LPPOINT lpPoint)
|
{
|
{
|
if(!hwnd || !lpPoint)
|
if(!hwnd || !lpPoint)
|
return FALSE;
|
return FALSE;
|
MapWindowPoints(NULL, hwnd, lpPoint, 1);
|
MapWindowPoints(NULL, hwnd, lpPoint, 1);
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
int WINAPI
|
int WINAPI
|
MapWindowPoints(HWND hwndFrom, HWND hwndTo, LPPOINT lpPoints, UINT cPoints)
|
MapWindowPoints(HWND hwndFrom, HWND hwndTo, LPPOINT lpPoints, UINT cPoints)
|
{
|
{
|
MWCOORD offx = 0;
|
MWCOORD offx = 0;
|
MWCOORD offy = 0;
|
MWCOORD offy = 0;
|
|
|
/* map src window to screen coords*/
|
/* map src window to screen coords*/
|
if(hwndFrom) {
|
if(hwndFrom) {
|
offx = hwndFrom->clirect.left;
|
offx = hwndFrom->clirect.left;
|
offy = hwndFrom->clirect.top;
|
offy = hwndFrom->clirect.top;
|
}
|
}
|
|
|
/* map to dst window client coords*/
|
/* map to dst window client coords*/
|
if(hwndTo) {
|
if(hwndTo) {
|
offx -= hwndTo->clirect.left;
|
offx -= hwndTo->clirect.left;
|
offy -= hwndTo->clirect.top;
|
offy -= hwndTo->clirect.top;
|
}
|
}
|
|
|
/* adjust points*/
|
/* adjust points*/
|
while(cPoints--) {
|
while(cPoints--) {
|
lpPoints->x += offx;
|
lpPoints->x += offx;
|
lpPoints->y += offy;
|
lpPoints->y += offy;
|
++lpPoints;
|
++lpPoints;
|
}
|
}
|
return (int)MAKELONG(offx, offy);
|
return (int)MAKELONG(offx, offy);
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
SetRect(LPRECT lprc, int xLeft, int yTop, int xRight, int yBottom)
|
SetRect(LPRECT lprc, int xLeft, int yTop, int xRight, int yBottom)
|
{
|
{
|
lprc->left = xLeft;
|
lprc->left = xLeft;
|
lprc->top = yTop;
|
lprc->top = yTop;
|
lprc->right = xRight;
|
lprc->right = xRight;
|
lprc->bottom = yBottom;
|
lprc->bottom = yBottom;
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
SetRectEmpty(LPRECT lprc)
|
SetRectEmpty(LPRECT lprc)
|
{
|
{
|
lprc->left = lprc->right = lprc->top = lprc->bottom = 0;
|
lprc->left = lprc->right = lprc->top = lprc->bottom = 0;
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
CopyRect(LPRECT lprcDst, CONST RECT *lprcSrc)
|
CopyRect(LPRECT lprcDst, CONST RECT *lprcSrc)
|
{
|
{
|
*lprcDst = *lprcSrc;
|
*lprcDst = *lprcSrc;
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
IsRectEmpty(CONST RECT *lprc)
|
IsRectEmpty(CONST RECT *lprc)
|
{
|
{
|
/* FIXME: should this just be ==, not <= ?*/
|
/* FIXME: should this just be ==, not <= ?*/
|
/*return lprc->left == lprc->right || lprc->top == lprc->bottom;*/
|
/*return lprc->left == lprc->right || lprc->top == lprc->bottom;*/
|
return lprc->right <= lprc->left || lprc->bottom <= lprc->top;
|
return lprc->right <= lprc->left || lprc->bottom <= lprc->top;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
InflateRect(LPRECT lprc, int dx, int dy)
|
InflateRect(LPRECT lprc, int dx, int dy)
|
{
|
{
|
lprc->left -= dx;
|
lprc->left -= dx;
|
lprc->top -= dy;
|
lprc->top -= dy;
|
lprc->right += dx;
|
lprc->right += dx;
|
lprc->bottom += dy;
|
lprc->bottom += dy;
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
OffsetRect(LPRECT lprc, int dx, int dy)
|
OffsetRect(LPRECT lprc, int dx, int dy)
|
{
|
{
|
lprc->left += dx;
|
lprc->left += dx;
|
lprc->right += dx;
|
lprc->right += dx;
|
lprc->top += dy;
|
lprc->top += dy;
|
lprc->bottom += dy;
|
lprc->bottom += dy;
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
/* PtInRect is #defined to MwPTINRECT because of bcc struct passing bug*/
|
/* PtInRect is #defined to MwPTINRECT because of bcc struct passing bug*/
|
BOOL WINAPI
|
BOOL WINAPI
|
MwPTINRECT(CONST RECT *lprc, POINT pt)
|
MwPTINRECT(CONST RECT *lprc, POINT pt)
|
{
|
{
|
return (pt.x >= lprc->left && pt.x < lprc->right &&
|
return (pt.x >= lprc->left && pt.x < lprc->right &&
|
pt.y >= lprc->top && pt.y < lprc->bottom);
|
pt.y >= lprc->top && pt.y < lprc->bottom);
|
}
|
}
|
|
|
LONG WINAPI
|
LONG WINAPI
|
GetWindowLong(HWND hwnd, int nIndex)
|
GetWindowLong(HWND hwnd, int nIndex)
|
{
|
{
|
switch(nIndex) {
|
switch(nIndex) {
|
case GWL_WNDPROC:
|
case GWL_WNDPROC:
|
return (LONG)hwnd->pClass->lpfnWndProc;
|
return (LONG)hwnd->pClass->lpfnWndProc;
|
case GWL_HINSTANCE:
|
case GWL_HINSTANCE:
|
/* nyi*/
|
/* nyi*/
|
break;
|
break;
|
case GWL_HWNDPARENT:
|
case GWL_HWNDPARENT:
|
return (LONG)hwnd->parent;
|
return (LONG)hwnd->parent;
|
case GWL_ID:
|
case GWL_ID:
|
return hwnd->id;
|
return hwnd->id;
|
case GWL_STYLE:
|
case GWL_STYLE:
|
return hwnd->style;
|
return hwnd->style;
|
case GWL_EXSTYLE:
|
case GWL_EXSTYLE:
|
return hwnd->exstyle;
|
return hwnd->exstyle;
|
case GWL_USERDATA:
|
case GWL_USERDATA:
|
return hwnd->userdata;
|
return hwnd->userdata;
|
default:
|
default:
|
if(nIndex+3 < hwnd->nextrabytes)
|
if(nIndex+3 < hwnd->nextrabytes)
|
return *(LONG *)&hwnd->extrabytes[nIndex];
|
return *(LONG *)&hwnd->extrabytes[nIndex];
|
}
|
}
|
return 0;
|
return 0;
|
}
|
}
|
|
|
LONG WINAPI
|
LONG WINAPI
|
SetWindowLong(HWND hwnd, int nIndex, LONG lNewLong)
|
SetWindowLong(HWND hwnd, int nIndex, LONG lNewLong)
|
{
|
{
|
LONG oldval = 0;
|
LONG oldval = 0;
|
|
|
switch(nIndex) {
|
switch(nIndex) {
|
case GWL_USERDATA:
|
case GWL_USERDATA:
|
oldval = hwnd->userdata;
|
oldval = hwnd->userdata;
|
hwnd->userdata = lNewLong;
|
hwnd->userdata = lNewLong;
|
break;
|
break;
|
case GWL_WNDPROC:
|
case GWL_WNDPROC:
|
oldval = (LONG)hwnd->pClass->lpfnWndProc;
|
oldval = (LONG)hwnd->pClass->lpfnWndProc;
|
hwnd->pClass->lpfnWndProc = (WNDPROC)lNewLong;
|
hwnd->pClass->lpfnWndProc = (WNDPROC)lNewLong;
|
break;
|
break;
|
case GWL_HINSTANCE:
|
case GWL_HINSTANCE:
|
case GWL_HWNDPARENT:
|
case GWL_HWNDPARENT:
|
case GWL_ID:
|
case GWL_ID:
|
case GWL_STYLE:
|
case GWL_STYLE:
|
case GWL_EXSTYLE:
|
case GWL_EXSTYLE:
|
/* nyi*/
|
/* nyi*/
|
break;
|
break;
|
default:
|
default:
|
if(nIndex+3 < hwnd->nextrabytes) {
|
if(nIndex+3 < hwnd->nextrabytes) {
|
oldval = GetWindowLong(hwnd, nIndex);
|
oldval = GetWindowLong(hwnd, nIndex);
|
*(LONG *)&hwnd->extrabytes[nIndex] = lNewLong;
|
*(LONG *)&hwnd->extrabytes[nIndex] = lNewLong;
|
}
|
}
|
break;
|
break;
|
}
|
}
|
return oldval;
|
return oldval;
|
}
|
}
|
|
|
WORD WINAPI
|
WORD WINAPI
|
GetWindowWord(HWND hwnd, int nIndex)
|
GetWindowWord(HWND hwnd, int nIndex)
|
{
|
{
|
if(nIndex+1 < hwnd->nextrabytes)
|
if(nIndex+1 < hwnd->nextrabytes)
|
return *(WORD *)&hwnd->extrabytes[nIndex];
|
return *(WORD *)&hwnd->extrabytes[nIndex];
|
return 0;
|
return 0;
|
}
|
}
|
|
|
WORD WINAPI
|
WORD WINAPI
|
SetWindowWord(HWND hwnd, int nIndex, WORD wNewWord)
|
SetWindowWord(HWND hwnd, int nIndex, WORD wNewWord)
|
{
|
{
|
WORD oldval = 0;
|
WORD oldval = 0;
|
|
|
if(nIndex+1 < hwnd->nextrabytes) {
|
if(nIndex+1 < hwnd->nextrabytes) {
|
oldval = GetWindowWord(hwnd, nIndex);
|
oldval = GetWindowWord(hwnd, nIndex);
|
*(WORD *)&hwnd->extrabytes[nIndex] = wNewWord;
|
*(WORD *)&hwnd->extrabytes[nIndex] = wNewWord;
|
}
|
}
|
return oldval;
|
return oldval;
|
}
|
}
|
|
|
DWORD WINAPI
|
DWORD WINAPI
|
GetClassLong(HWND hwnd, int nIndex)
|
GetClassLong(HWND hwnd, int nIndex)
|
{
|
{
|
switch(nIndex) {
|
switch(nIndex) {
|
case GCL_HBRBACKGROUND:
|
case GCL_HBRBACKGROUND:
|
return (DWORD)hwnd->pClass->hbrBackground;
|
return (DWORD)hwnd->pClass->hbrBackground;
|
case GCL_CBWNDEXTRA:
|
case GCL_CBWNDEXTRA:
|
return (DWORD)hwnd->pClass->cbWndExtra;
|
return (DWORD)hwnd->pClass->cbWndExtra;
|
}
|
}
|
return 0;
|
return 0;
|
}
|
}
|
|
|
int WINAPI
|
int WINAPI
|
GetWindowTextLength(HWND hwnd)
|
GetWindowTextLength(HWND hwnd)
|
{
|
{
|
return SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0L);
|
return SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0L);
|
}
|
}
|
|
|
int WINAPI
|
int WINAPI
|
GetWindowText(HWND hwnd, LPSTR lpString, int nMaxCount)
|
GetWindowText(HWND hwnd, LPSTR lpString, int nMaxCount)
|
{
|
{
|
return SendMessage(hwnd, WM_GETTEXT, nMaxCount,(LPARAM)(LPSTR)lpString);
|
return SendMessage(hwnd, WM_GETTEXT, nMaxCount,(LPARAM)(LPSTR)lpString);
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
SetWindowText(HWND hwnd, LPCSTR lpString)
|
SetWindowText(HWND hwnd, LPCSTR lpString)
|
{
|
{
|
return SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)(LPCSTR)lpString);
|
return SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)(LPCSTR)lpString);
|
}
|
}
|
|
|
/* Recursively offset all children of passed window*/
|
/* Recursively offset all children of passed window*/
|
static void
|
static void
|
MwOffsetChildren(HWND hwnd, int offx, int offy)
|
MwOffsetChildren(HWND hwnd, int offx, int offy)
|
{
|
{
|
HWND cp;
|
HWND cp;
|
|
|
/* offset all child windows for move*/
|
/* offset all child windows for move*/
|
for(cp=hwnd->children; cp; cp=cp->siblings) {
|
for(cp=hwnd->children; cp; cp=cp->siblings) {
|
|
|
/* offset window and client area rects*/
|
/* offset window and client area rects*/
|
OffsetRect(&cp->winrect, offx, offy);
|
OffsetRect(&cp->winrect, offx, offy);
|
OffsetRect(&cp->clirect, offx, offy);
|
OffsetRect(&cp->clirect, offx, offy);
|
|
|
/* offset scrollbar NC hittest rects*/
|
/* offset scrollbar NC hittest rects*/
|
if(!IsRectEmpty(&cp->vscroll.rc))
|
if(!IsRectEmpty(&cp->vscroll.rc))
|
OffsetRect(&cp->vscroll.rc, offx, offy);
|
OffsetRect(&cp->vscroll.rc, offx, offy);
|
if(!IsRectEmpty(&cp->hscroll.rc))
|
if(!IsRectEmpty(&cp->hscroll.rc))
|
OffsetRect(&cp->hscroll.rc, offx, offy);
|
OffsetRect(&cp->hscroll.rc, offx, offy);
|
MwOffsetChildren(cp, offx, offy);
|
MwOffsetChildren(cp, offx, offy);
|
}
|
}
|
}
|
}
|
|
|
BOOL
|
BOOL
|
SetWindowPos(HWND hwnd, HWND hwndInsertAfter, int x, int y, int cx, int cy,
|
SetWindowPos(HWND hwnd, HWND hwndInsertAfter, int x, int y, int cx, int cy,
|
UINT fuFlags)
|
UINT fuFlags)
|
{
|
{
|
int hidden;
|
int hidden;
|
BOOL bMove, bSize, bZorder;
|
BOOL bMove, bSize, bZorder;
|
MWCOORD offx = 0, offy = 0; /* = 0 for bad gcc warning*/
|
MWCOORD offx = 0, offy = 0; /* = 0 for bad gcc warning*/
|
WINDOWPOS winpos;
|
WINDOWPOS winpos;
|
|
|
if(!hwnd || hwnd == rootwp || cx < 0 || cy < 0)
|
if(!hwnd || hwnd == rootwp || cx < 0 || cy < 0)
|
return FALSE;
|
return FALSE;
|
|
|
/* FIXME SWP_NOACTIVATE*/
|
/* FIXME SWP_NOACTIVATE*/
|
|
|
if((fuFlags & SWP_SHOWWINDOW))
|
if((fuFlags & SWP_SHOWWINDOW))
|
return ShowWindow(hwnd, SW_SHOW);
|
return ShowWindow(hwnd, SW_SHOW);
|
|
|
if((fuFlags & SWP_HIDEWINDOW))
|
if((fuFlags & SWP_HIDEWINDOW))
|
return ShowWindow(hwnd, SW_HIDE);
|
return ShowWindow(hwnd, SW_HIDE);
|
|
|
/* move is relative to parent's client rect for child windows*/
|
/* move is relative to parent's client rect for child windows*/
|
if(hwnd->style & WS_CHILD) {
|
if(hwnd->style & WS_CHILD) {
|
x += hwnd->parent->clirect.left;
|
x += hwnd->parent->clirect.left;
|
y += hwnd->parent->clirect.top;
|
y += hwnd->parent->clirect.top;
|
} else {
|
} else {
|
x += hwnd->parent->winrect.left;
|
x += hwnd->parent->winrect.left;
|
y += hwnd->parent->winrect.top;
|
y += hwnd->parent->winrect.top;
|
}
|
}
|
|
|
bMove = !(fuFlags & SWP_NOMOVE) &&
|
bMove = !(fuFlags & SWP_NOMOVE) &&
|
(hwnd->winrect.left != x || hwnd->winrect.top != y);
|
(hwnd->winrect.left != x || hwnd->winrect.top != y);
|
bSize = !(fuFlags & SWP_NOSIZE) &&
|
bSize = !(fuFlags & SWP_NOSIZE) &&
|
((hwnd->winrect.right - hwnd->winrect.left) != cx ||
|
((hwnd->winrect.right - hwnd->winrect.left) != cx ||
|
(hwnd->winrect.bottom - hwnd->winrect.top) != cy);
|
(hwnd->winrect.bottom - hwnd->winrect.top) != cy);
|
bZorder = !(fuFlags & SWP_NOZORDER);
|
bZorder = !(fuFlags & SWP_NOZORDER);
|
if(!bMove && !bSize && !bZorder)
|
if(!bMove && !bSize && !bZorder)
|
return TRUE;
|
return TRUE;
|
|
|
/* could optimize to not require redraw when possible*/
|
/* could optimize to not require redraw when possible*/
|
hidden = hwnd->unmapcount || (fuFlags & SWP_NOREDRAW);
|
hidden = hwnd->unmapcount || (fuFlags & SWP_NOREDRAW);
|
|
|
if(bZorder) {
|
if(bZorder) {
|
switch((int)hwndInsertAfter) {
|
switch((int)hwndInsertAfter) {
|
case (int)HWND_TOP:
|
case (int)HWND_TOP:
|
MwRaiseWindow(hwnd);
|
MwRaiseWindow(hwnd);
|
break;
|
break;
|
case (int)HWND_BOTTOM:
|
case (int)HWND_BOTTOM:
|
MwLowerWindow(hwnd);
|
MwLowerWindow(hwnd);
|
break;
|
break;
|
default:
|
default:
|
/* FIXME for non top/bottom zorder*/
|
/* FIXME for non top/bottom zorder*/
|
break;
|
break;
|
}
|
}
|
} else {
|
} else {
|
if(!hidden)
|
if(!hidden)
|
MwHideWindow(hwnd, FALSE, FALSE);
|
MwHideWindow(hwnd, FALSE, FALSE);
|
}
|
}
|
|
|
if(bMove) {
|
if(bMove) {
|
offx = x - hwnd->winrect.left;
|
offx = x - hwnd->winrect.left;
|
offy = y - hwnd->winrect.top;
|
offy = y - hwnd->winrect.top;
|
}
|
}
|
if(bMove || bSize) {
|
if(bMove || bSize) {
|
hwnd->winrect.left = x;
|
hwnd->winrect.left = x;
|
hwnd->winrect.top = y;
|
hwnd->winrect.top = y;
|
hwnd->winrect.right = x + cx;
|
hwnd->winrect.right = x + cx;
|
hwnd->winrect.bottom = y + cy;
|
hwnd->winrect.bottom = y + cy;
|
}
|
}
|
if(bMove)
|
if(bMove)
|
MwOffsetChildren(hwnd, offx, offy);
|
MwOffsetChildren(hwnd, offx, offy);
|
|
|
if(bMove || bSize) {
|
if(bMove || bSize) {
|
MwCalcClientRect(hwnd);
|
MwCalcClientRect(hwnd);
|
|
|
/* send windowposchanged message*/
|
/* send windowposchanged message*/
|
/* FIXME: move WM_MOVE, WM_SIZE to defwndproc*/
|
/* FIXME: move WM_MOVE, WM_SIZE to defwndproc*/
|
winpos.hwnd = hwnd;
|
winpos.hwnd = hwnd;
|
winpos.hwndInsertAfter = hwndInsertAfter;
|
winpos.hwndInsertAfter = hwndInsertAfter;
|
winpos.x = x;
|
winpos.x = x;
|
winpos.y = y;
|
winpos.y = y;
|
winpos.cx = cx;
|
winpos.cx = cx;
|
winpos.cy = cy;
|
winpos.cy = cy;
|
winpos.flags = fuFlags;
|
winpos.flags = fuFlags;
|
SendMessage(hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)&winpos);
|
SendMessage(hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)&winpos);
|
|
|
MwSendSizeMove(hwnd, bSize, bMove);
|
MwSendSizeMove(hwnd, bSize, bMove);
|
}
|
}
|
|
|
++mwpaintSerial; /* increment paint serial # for alphablending*/
|
++mwpaintSerial; /* increment paint serial # for alphablending*/
|
++mwpaintNC; /* increment paint serial # for NC painting*/
|
++mwpaintNC; /* increment paint serial # for NC painting*/
|
if(!bZorder && !hidden)
|
if(!bZorder && !hidden)
|
MwShowWindow(hwnd, FALSE);
|
MwShowWindow(hwnd, FALSE);
|
|
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
MoveWindow(HWND hwnd, int x, int y, int nWidth, int nHeight, BOOL bRepaint)
|
MoveWindow(HWND hwnd, int x, int y, int nWidth, int nHeight, BOOL bRepaint)
|
{
|
{
|
UINT flags = SWP_NOZORDER | SWP_NOACTIVATE;
|
UINT flags = SWP_NOZORDER | SWP_NOACTIVATE;
|
|
|
if(!bRepaint)
|
if(!bRepaint)
|
flags |= SWP_NOREDRAW;
|
flags |= SWP_NOREDRAW;
|
return SetWindowPos(hwnd, 0, x, y, nWidth, nHeight, flags);
|
return SetWindowPos(hwnd, 0, x, y, nWidth, nHeight, flags);
|
}
|
}
|
|
|
void
|
void
|
MwSendSizeMove(HWND hwnd, BOOL bSize, BOOL bMove)
|
MwSendSizeMove(HWND hwnd, BOOL bSize, BOOL bMove)
|
{
|
{
|
DWORD dwStyle;
|
DWORD dwStyle;
|
RECT rc;
|
RECT rc;
|
|
|
if(bSize) {
|
if(bSize) {
|
GetClientRect(hwnd, &rc);
|
GetClientRect(hwnd, &rc);
|
SendMessage(hwnd, WM_SIZE, SIZE_RESTORED,
|
SendMessage(hwnd, WM_SIZE, SIZE_RESTORED,
|
MAKELONG(rc.right, rc.bottom));
|
MAKELONG(rc.right, rc.bottom));
|
}
|
}
|
if(bMove) {
|
if(bMove) {
|
dwStyle = GetWindowLong(hwnd, GWL_STYLE);
|
dwStyle = GetWindowLong(hwnd, GWL_STYLE);
|
GetWindowRect(hwnd, &rc);
|
GetWindowRect(hwnd, &rc);
|
/* return parent coords for child windows*/
|
/* return parent coords for child windows*/
|
if(dwStyle & WS_CHILD)
|
if(dwStyle & WS_CHILD)
|
ScreenToClient(hwnd->parent, (LPPOINT)&rc.left);
|
ScreenToClient(hwnd->parent, (LPPOINT)&rc.left);
|
SendMessage(hwnd, WM_MOVE, 0, MAKELONG(rc.left, rc.top));
|
SendMessage(hwnd, WM_MOVE, 0, MAKELONG(rc.left, rc.top));
|
}
|
}
|
}
|
}
|
|
|
/*
|
/*
|
* Specify a cursor for a window.
|
* Specify a cursor for a window.
|
* This cursor will only be used within that window, and by default
|
* This cursor will only be used within that window, and by default
|
* for its new children. If the cursor is currently within this
|
* for its new children. If the cursor is currently within this
|
* window, it will be changed to the new one immediately.
|
* window, it will be changed to the new one immediately.
|
*/
|
*/
|
void
|
void
|
MwSetCursor(HWND wp, PMWCURSOR pcursor)
|
MwSetCursor(HWND wp, PMWCURSOR pcursor)
|
{
|
{
|
HCURSOR cp;
|
HCURSOR cp;
|
int bytes;
|
int bytes;
|
|
|
if(!wp || !pcursor)
|
if(!wp || !pcursor)
|
return;
|
return;
|
|
|
bytes = MWIMAGE_SIZE(pcursor->width,pcursor->height)
|
bytes = MWIMAGE_SIZE(pcursor->width,pcursor->height)
|
* sizeof(MWIMAGEBITS);
|
* sizeof(MWIMAGEBITS);
|
|
|
/*
|
/*
|
* See if the window is using a shared cursor definition.
|
* See if the window is using a shared cursor definition.
|
* If so, then allocate a new private one, otherwise reuse it.
|
* If so, then allocate a new private one, otherwise reuse it.
|
*/
|
*/
|
cp = wp->cursor;
|
cp = wp->cursor;
|
if (!cp || cp->usecount-- > 1) {
|
if (!cp || cp->usecount-- > 1) {
|
cp = GdItemNew(struct hcursor);
|
cp = GdItemNew(struct hcursor);
|
if(!cp)
|
if(!cp)
|
return;
|
return;
|
}
|
}
|
|
|
cp->usecount = 1;
|
cp->usecount = 1;
|
cp->cursor.width = pcursor->width;
|
cp->cursor.width = pcursor->width;
|
cp->cursor.height = pcursor->height;
|
cp->cursor.height = pcursor->height;
|
cp->cursor.hotx = pcursor->hotx;
|
cp->cursor.hotx = pcursor->hotx;
|
cp->cursor.hoty = pcursor->hoty;
|
cp->cursor.hoty = pcursor->hoty;
|
cp->cursor.fgcolor = pcursor->fgcolor;
|
cp->cursor.fgcolor = pcursor->fgcolor;
|
cp->cursor.bgcolor = pcursor->bgcolor;
|
cp->cursor.bgcolor = pcursor->bgcolor;
|
memcpy(cp->cursor.image, pcursor->image, bytes);
|
memcpy(cp->cursor.image, pcursor->image, bytes);
|
memcpy(cp->cursor.mask, pcursor->mask, bytes);
|
memcpy(cp->cursor.mask, pcursor->mask, bytes);
|
wp->cursor = cp;
|
wp->cursor = cp;
|
|
|
/*
|
/*
|
* If this was the current cursor, then draw the new one.
|
* If this was the current cursor, then draw the new one.
|
*/
|
*/
|
if (cp == curcursor || curcursor == NULL) {
|
if (cp == curcursor || curcursor == NULL) {
|
GdMoveCursor(cursorx - cp->cursor.hotx,
|
GdMoveCursor(cursorx - cp->cursor.hotx,
|
cursory - cp->cursor.hoty);
|
cursory - cp->cursor.hoty);
|
GdSetCursor(&cp->cursor);
|
GdSetCursor(&cp->cursor);
|
}
|
}
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
GetCursorPos(LPPOINT lpPoint)
|
GetCursorPos(LPPOINT lpPoint)
|
{
|
{
|
MWCOORD x, y;
|
MWCOORD x, y;
|
|
|
if(lpPoint) {
|
if(lpPoint) {
|
GdGetCursorPos(&x, &y);
|
GdGetCursorPos(&x, &y);
|
lpPoint->x = x;
|
lpPoint->x = x;
|
lpPoint->y = y;
|
lpPoint->y = y;
|
return TRUE;
|
return TRUE;
|
}
|
}
|
return FALSE;
|
return FALSE;
|
}
|
}
|
|
|
HWND WINAPI
|
HWND WINAPI
|
GetCapture(VOID)
|
GetCapture(VOID)
|
{
|
{
|
return capturewp;
|
return capturewp;
|
}
|
}
|
|
|
HWND WINAPI
|
HWND WINAPI
|
SetCapture(HWND hwnd)
|
SetCapture(HWND hwnd)
|
{
|
{
|
HWND oldCapture = capturewp;
|
HWND oldCapture = capturewp;
|
|
|
capturewp = hwnd;
|
capturewp = hwnd;
|
MwCheckMouseWindow();
|
MwCheckMouseWindow();
|
return oldCapture;
|
return oldCapture;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
ReleaseCapture(VOID)
|
ReleaseCapture(VOID)
|
{
|
{
|
capturewp = NULL;
|
capturewp = NULL;
|
MwCheckMouseWindow();
|
MwCheckMouseWindow();
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
struct timer { /* private timer structure*/
|
struct timer { /* private timer structure*/
|
HWND hwnd; /* window associated with timer, NULL if none*/
|
HWND hwnd; /* window associated with timer, NULL if none*/
|
UINT idTimer; /* id for timer*/
|
UINT idTimer; /* id for timer*/
|
UINT uTimeout; /* timeout value, in msecs*/
|
UINT uTimeout; /* timeout value, in msecs*/
|
DWORD dwClockExpires; /* GetTickCount timer expiration value*/
|
DWORD dwClockExpires; /* GetTickCount timer expiration value*/
|
TIMERPROC lpTimerFunc; /* callback function*/
|
TIMERPROC lpTimerFunc; /* callback function*/
|
};
|
};
|
|
|
static struct timer timer; /* single global timer FIXME*/
|
static struct timer timer; /* single global timer FIXME*/
|
|
|
UINT WINAPI
|
UINT WINAPI
|
SetTimer(HWND hwnd, UINT idTimer, UINT uTimeout, TIMERPROC lpTimerFunc)
|
SetTimer(HWND hwnd, UINT idTimer, UINT uTimeout, TIMERPROC lpTimerFunc)
|
{
|
{
|
static UINT nextID = 0; /* next ID when hwnd is NULL*/
|
static UINT nextID = 0; /* next ID when hwnd is NULL*/
|
|
|
/* assign timer id based on valid window handle*/
|
/* assign timer id based on valid window handle*/
|
timer.hwnd = hwnd;
|
timer.hwnd = hwnd;
|
timer.idTimer = hwnd? idTimer: ++nextID;
|
timer.idTimer = hwnd? idTimer: ++nextID;
|
timer.uTimeout = uTimeout;
|
timer.uTimeout = uTimeout;
|
timer.dwClockExpires = GetTickCount() + uTimeout;
|
timer.dwClockExpires = GetTickCount() + uTimeout;
|
timer.lpTimerFunc = lpTimerFunc;
|
timer.lpTimerFunc = lpTimerFunc;
|
|
|
return timer.idTimer;
|
return timer.idTimer;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
KillTimer(HWND hwnd, UINT idTimer)
|
KillTimer(HWND hwnd, UINT idTimer)
|
{
|
{
|
if(timer.hwnd == hwnd && timer.idTimer == idTimer) {
|
if(timer.hwnd == hwnd && timer.idTimer == idTimer) {
|
timer.uTimeout = 0;
|
timer.uTimeout = 0;
|
return TRUE;
|
return TRUE;
|
}
|
}
|
return FALSE;
|
return FALSE;
|
}
|
}
|
|
|
/*
|
/*
|
* Return the next timeout value in msecs
|
* Return the next timeout value in msecs
|
*/
|
*/
|
UINT
|
UINT
|
MwGetNextTimeoutValue(void)
|
MwGetNextTimeoutValue(void)
|
{
|
{
|
int timeout;
|
int timeout;
|
|
|
if(timer.uTimeout) {
|
if(timer.uTimeout) {
|
timeout = timer.dwClockExpires - GetTickCount();
|
timeout = timer.dwClockExpires - GetTickCount();
|
if(timeout > 0)
|
if(timeout > 0)
|
return timeout;
|
return timeout;
|
}
|
}
|
return 0;
|
return 0;
|
}
|
}
|
|
|
/*
|
/*
|
* Check if any timers have expired by looking at current system ticks
|
* Check if any timers have expired by looking at current system ticks
|
*/
|
*/
|
void
|
void
|
MwHandleTimers(void)
|
MwHandleTimers(void)
|
{
|
{
|
int timeout;
|
int timeout;
|
DWORD dwTime;
|
DWORD dwTime;
|
|
|
/* check if timer running*/
|
/* check if timer running*/
|
if(timer.uTimeout == 0)
|
if(timer.uTimeout == 0)
|
return;
|
return;
|
|
|
/* determine if timer expired*/
|
/* determine if timer expired*/
|
dwTime = GetTickCount();
|
dwTime = GetTickCount();
|
timeout = timer.dwClockExpires - dwTime;
|
timeout = timer.dwClockExpires - dwTime;
|
if(timeout > 0)
|
if(timeout > 0)
|
return;
|
return;
|
|
|
/* call timer function or post timer message*/
|
/* call timer function or post timer message*/
|
if(timer.lpTimerFunc)
|
if(timer.lpTimerFunc)
|
timer.lpTimerFunc(timer.hwnd, WM_TIMER, timer.idTimer, dwTime);
|
timer.lpTimerFunc(timer.hwnd, WM_TIMER, timer.idTimer, dwTime);
|
else PostMessage(timer.hwnd, WM_TIMER, timer.idTimer, 0);
|
else PostMessage(timer.hwnd, WM_TIMER, timer.idTimer, 0);
|
|
|
/* reset timer*/
|
/* reset timer*/
|
timer.dwClockExpires = dwTime + timer.uTimeout;
|
timer.dwClockExpires = dwTime + timer.uTimeout;
|
}
|
}
|
|
|
int WINAPI
|
int WINAPI
|
GetSystemMetrics(int nIndex)
|
GetSystemMetrics(int nIndex)
|
{
|
{
|
switch(nIndex) {
|
switch(nIndex) {
|
case SM_CXSCREEN:
|
case SM_CXSCREEN:
|
return scrdev.xvirtres;
|
return scrdev.xvirtres;
|
case SM_CYSCREEN:
|
case SM_CYSCREEN:
|
return scrdev.yvirtres;
|
return scrdev.yvirtres;
|
case SM_CXVSCROLL:
|
case SM_CXVSCROLL:
|
return mwSYSMETRICS_CXVSCROLL;
|
return mwSYSMETRICS_CXVSCROLL;
|
case SM_CYHSCROLL:
|
case SM_CYHSCROLL:
|
return mwSYSMETRICS_CYHSCROLL;
|
return mwSYSMETRICS_CYHSCROLL;
|
case SM_CYCAPTION:
|
case SM_CYCAPTION:
|
/* + 1 for line under caption*/
|
/* + 1 for line under caption*/
|
return mwSYSMETRICS_CYCAPTION + 1;
|
return mwSYSMETRICS_CYCAPTION + 1;
|
case SM_CXBORDER:
|
case SM_CXBORDER:
|
return mwSYSMETRICS_CXBORDER;
|
return mwSYSMETRICS_CXBORDER;
|
case SM_CYBORDER:
|
case SM_CYBORDER:
|
return mwSYSMETRICS_CYBORDER;
|
return mwSYSMETRICS_CYBORDER;
|
case SM_CYMENU:
|
case SM_CYMENU:
|
break; /* FIXME: 19 when menubars work*/
|
break; /* FIXME: 19 when menubars work*/
|
case SM_CYVSCROLL:
|
case SM_CYVSCROLL:
|
return mwSYSMETRICS_CYVSCROLL;
|
return mwSYSMETRICS_CYVSCROLL;
|
case SM_CXHSCROLL:
|
case SM_CXHSCROLL:
|
return mwSYSMETRICS_CXHSCROLL;
|
return mwSYSMETRICS_CXHSCROLL;
|
case SM_CXFRAME:
|
case SM_CXFRAME:
|
case SM_CXDLGFRAME:
|
case SM_CXDLGFRAME:
|
return mwSYSMETRICS_CXFRAME;
|
return mwSYSMETRICS_CXFRAME;
|
case SM_CYFRAME:
|
case SM_CYFRAME:
|
case SM_CYDLGFRAME:
|
case SM_CYDLGFRAME:
|
return mwSYSMETRICS_CYFRAME;
|
return mwSYSMETRICS_CYFRAME;
|
}
|
}
|
return 0;
|
return 0;
|
}
|
}
|
|
|
HWND WINAPI
|
HWND WINAPI
|
GetDlgItem(HWND hDlg, int nIDDlgItem)
|
GetDlgItem(HWND hDlg, int nIDDlgItem)
|
{
|
{
|
HWND wp;
|
HWND wp;
|
|
|
if(hDlg) {
|
if(hDlg) {
|
for(wp=hDlg->children; wp; wp=wp->siblings)
|
for(wp=hDlg->children; wp; wp=wp->siblings)
|
if(wp->id == nIDDlgItem)
|
if(wp->id == nIDDlgItem)
|
return wp;
|
return wp;
|
}
|
}
|
return 0;
|
return 0;
|
}
|
}
|
|
|