📄 win_win32.c
字号:
#endif
}
static void WinControlDelete(win* p,wincontrol* Control)
{
wincontrol** i;
for (i=&p->Controls;*i && *i!=Control;i=&(*i)->Next);
if (*i)
*i = Control->Next;
if (!Control->External)
{
if (Control->Control)
DestroyWindow(Control->Control);
if (Control->Edit)
DestroyWindow(Control->Edit);
}
free(Control);
}
static void WinClear( win* p)
{
p->Focus = NULL;
while (p->Controls)
WinControlDelete(p,p->Controls);
}
void WinBeginUpdate(win* p)
{
ShowWindow(p->WndDialog,SW_HIDE);
WinClear(p);
}
void WinEndUpdate(win* p)
{
if (!p->Focus)
WinNext(p,0);
ShowWindow(p->WndDialog,SW_SHOWNA);
WinUpdateScroll(p);
}
void WinMenuInsert(win* p,int No,int PrevId,int Id,const tchar_t* LockedMsg)
{
if (p->Menu2[No])
InsertMenu(p->Menu2[No],PrevId,MF_BYCOMMAND|MF_STRING,Id,LockedMsg);
}
bool_t WinMenuDelete(win* p,int No,int Id)
{
if (p->Menu2[No])
return DeleteMenu(p->Menu2[No],Id,MF_BYCOMMAND)!=0;
return 0;
}
bool_t WinMenuEnable(win* p,int No,int Id,bool_t State)
{
if (p->Menu2[No])
return EnableMenuItem(p->Menu2[No],Id,(State ? MF_ENABLED:MF_GRAYED)|MF_BYCOMMAND) != -1;
return 0;
}
int WinMenuFind(win* p,int Id)
{
int No;
MENUITEMINFO Info;
if (p->Menu3)
return 0;
Info.cbSize = sizeof(Info);
Info.fMask = 0;
for (No=0;No<2;++No)
{
if (p->Menu2[No] && GetMenuItemInfo(p->Menu2[No],Id,FALSE,&Info))
return No;
}
return 0;
}
bool_t WinMenuCheck(win* p,int No,int Id,bool_t State)
{
if (p->Menu2[No])
return CheckMenuItem(p->Menu2[No],Id,State?MF_CHECKED:MF_UNCHECKED) != -1;
return 0;
}
void WinTitle(win* p,const tchar_t* LockedMsg)
{
SetWindowText(p->Wnd,LockedMsg);
}
int WinClose(win* p)
{
PostMessage(p->Wnd,WM_CLOSE,0,0);
return ERR_NONE;
}
wincontrol* WinLabel(win* p,winunit* DlgTop,winunit DlgLeft,winunit DlgWidth,const tchar_t* Msg,int FontSize,int Flags,wincontrol* Ref)
{
tchar_t s[256];
wincontrol* Result = NULL;
SIZE Size;
HDC DC = GetDC(p->Wnd);
HFONT OldFont;
HFONT Font = (HFONT)WinFont(p,&FontSize,(Flags & LABEL_BOLD)!=0);
int Style = WS_VISIBLE | WS_CHILD;
int Left,Width;
int Extra = WinUnitToPixelX(p,2);
if (DlgLeft<0)
{
DlgLeft = 2;
DlgWidth = p->Width-4;
}
Left = WinUnitToPixelX(p,DlgLeft);
Width = DlgWidth>0 ? WinUnitToPixelX(p,DlgWidth) : -1;
if (Ref)
Style |= SS_NOTIFY;
if (Flags & LABEL_CENTER)
Style |= SS_CENTER;
else
Style |= SS_LEFTNOWORDWRAP;
OldFont = SelectObject(DC,Font);
if (Msg)
while (*Msg)
{
while (*Msg == 10)
{
++Msg;
*DlgTop += FontSize/3; // smaller gaps
}
if (*Msg)
{
tchar_t* i;
wincontrol* Control = CreateControl(p,sizeof(wincontrol));
if (!Control)
break;
tcscpy_s(s,TSIZEOF(s),Msg);
i = tcschr(s,10);
if (i) *i = 0;
for (;;)
{
GetTextExtentPoint(DC,s,tcslen(s),&Size);
Size.cx += Extra;
if (!s[0] || !s[1] || Width<0 || Size.cx <= Width)
break;
i = tcsrchr(s,' ');
if (i)
*i = 0;
else
s[tcslen(s)-1] = 0;
}
Control->Disabled = 1; // no user input
Control->Ref = Ref;
Control->Control = CreateWindow(T("STATIC"),s,Style,Left,WinUnitToPixelY(p,*DlgTop),
Width>0 ? Width : Size.cx, WinUnitToPixelY(p,FontSize), p->WndDialog, NULL, p->Module, NULL );
SetWindowLong(Control->Control,GWL_USERDATA,(LONG)Control);
SendMessage(Control->Control,WM_SETFONT,(WPARAM)Font,0);
*DlgTop += FontSize;
Msg += tcslen(s);
while (*Msg == ' ') ++Msg;
if (*Msg == 10) ++Msg;
if (!Result)
Result = Control;
}
}
SelectObject(DC,OldFont);
ReleaseDC(p->Wnd,DC);
return Result;
}
void* WinFont(win* p,winunit* FontSize,bool_t Bold)
{
HFONT Font;
int Size = WinUnitToPixelY(p,*FontSize);
if (Size && Size < MAXFONTSIZE)
{
if (!FontCache[Size][Bold])
{
LOGFONT LogFont;
memset(&LogFont,0,sizeof(LogFont));
tcscpy_s(LogFont.lfFaceName,TSIZEOF(LogFont.lfFaceName),T("MS Sans Serif"));
LogFont.lfHeight = Size;
LogFont.lfWidth = 0;
switch (Context()->Lang)
{
case FOURCC('A','R','_','_'):
LogFont.lfCharSet = ARABIC_CHARSET;
break;
case FOURCC('C','H','T','_'):
LogFont.lfCharSet = CHINESEBIG5_CHARSET;
break;
case FOURCC('C','H','S','_'):
LogFont.lfCharSet = GB2312_CHARSET;
break;
case FOURCC('R','U','_','_'):
LogFont.lfCharSet = RUSSIAN_CHARSET;
break;
case FOURCC('J','A','_','_'):
LogFont.lfCharSet = SHIFTJIS_CHARSET;
break;
case FOURCC('T','R','_','_'):
LogFont.lfCharSet = TURKISH_CHARSET;
break;
case FOURCC('K','O','_','_'):
LogFont.lfCharSet = HANGEUL_CHARSET;
break;
default:
LogFont.lfCharSet = OEM_CHARSET;
}
if (Bold)
LogFont.lfWeight = FW_BOLD;
FontCache[Size][Bold] = CreateFontIndirect(&LogFont);
}
Font = FontCache[Size][Bold];
}
else
{
LOGFONT LogFont;
Font = (HFONT)GetStockObject(SYSTEM_FONT);
GetObject(Font,sizeof(LogFont),&LogFont);
*FontSize = WinPixelToUnitY(p,abs(LogFont.lfHeight));
}
return Font;
}
static void UpdateDPI(win* p)
{
HDC DC = GetDC(p->Wnd);
p->LogPixelSX = GetDeviceCaps(DC, LOGPIXELSY);
p->LogPixelSY = GetDeviceCaps(DC, LOGPIXELSX);
p->ScreenWidth = WinPixelToUnitY(p,GetDeviceCaps(DC,HORZRES));
p->MenuSmall = WinPixelToUnitY(p,GetDeviceCaps(DC,VERTRES)) < 210;
ReleaseDC(p->Wnd,DC);
}
static void VScroll(win* p,int Cmd,int Delta);
static void HScroll(win* p,int Cmd,int Delta);
static void UpdateDialogSize(win* p)
{
RECT r;
GetClientRect(p->WndDialog,&r);
if (!p->ScrollV)
r.right -= GetSystemMetrics(SM_CXVSCROLL);
if (!p->ScrollH)
r.bottom -= GetSystemMetrics(SM_CYHSCROLL);
p->Width = WinPixelToUnitX(p,r.right);
p->Height = WinPixelToUnitY(p,r.bottom);
}
static void WinControlFocus(win* p,wincontrol* Control,bool_t Set)
{
wincontrol* i;
if (p->Focus == Control)
return;
if (Control && Control->Disabled)
return;
if (p->Focus)
for (i=p->Controls;i;i=i->Next)
if (i->Ref == p->Focus)
InvalidateRect(i->Control,NULL,TRUE);
p->Focus = Control;
if (Control)
{
POINT o;
RECT r;
int Min=MAX_INT;
int Max=-MAX_INT;
if (Control->Control && GetParent(Control->Control)==p->WndDialog)
{
GetWindowRect(Control->Control,&r);
if (r.bottom > Max)
Max = r.bottom;
if (r.top < Min)
Min = r.top;
}
for (i=p->Controls;i;i=i->Next)
if (i->Ref == Control)
{
GetWindowRect(i->Control,&r);
if (r.bottom > Max)
Max = r.bottom;
if (r.top < Min)
Min = r.top;
InvalidateRect(i->Control,NULL,TRUE);
}
if (Max > Min)
{
o.x = o.y = 0;
ClientToScreen(p->WndDialog,&o);
GetClientRect(p->WndDialog,&r);
r.top += o.y;
r.bottom += o.y;
if (r.top > Min)
VScroll(p,0,Max-r.bottom);
else
if (r.bottom < Max)
VScroll(p,0,Min-r.top);
}
if (Set)
if (Control->Control)
SetFocus(Control->Control);
else
SetFocus(p->WndDialog);
}
else
if (Set)
SetFocus(p->WndDialog);
}
static void WinNext(win* p,bool_t Prev)
{
wincontrol* Start = p->Focus;
wincontrol* Last;
wincontrol* i;
if (!Start)
{
Start = p->Controls;
if (!Start)
return;
if (!Start->Disabled)
{
WinControlFocus(p,Start,1);
return;
}
}
Last = Start;
do
{
if (Prev)
{
for (i=p->Controls;i->Next && i->Next!=Last;i=i->Next);
}
else
{
i = Last->Next;
if (!i)
i=p->Controls;
}
Last = i;
}
while (i && i!=Start && i->Disabled);
WinControlFocus(p,i,1);
}
void WinPropFocus(win* p, node* Node, int No, bool_t SetFocus)
{
wincontrol* Control;
for (Control=p->Controls;Control;Control=Control->Next)
if (Control->Pin.Node == Node && Control->Pin.No == No)
{
WinControlFocus(p,Control,SetFocus);
break;
}
}
void WinPropUpdate(win* p, node* Node, int No)
{
wincontrol* Control;
for (Control=p->Controls;Control;Control=Control->Next)
if (Control->Pin.Node == Node && Control->Pin.No == No)
WinControlUpdate(p,Control);
}
static LRESULT CALLBACK DialogProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
wincontrol* i;
int Result;
win* p = (win*)GetWindowLong(Wnd,GWL_USERDATA);
if (p && p->DialogProc && p->DialogProc(p,Msg,wParam,lParam,&Result))
return Result;
switch (Msg)
{
case WM_CREATE:
p = (win*)((CREATESTRUCT*)lParam)->lpCreateParams;
p->WndDialog = Wnd;
p->Controls = NULL;
p->Focus = NULL;
SetWindowLong(Wnd,GWL_USERDATA,(LONG)p);
break;
case WM_COMMAND:
i = (wincontrol*) GetWindowLong((HWND)lParam,GWL_USERDATA);
if (VALIDCONTROL(i))
WinControlCmd(p,i,(HWND)lParam,HIWORD(wParam));
break;
case WM_SIZE:
if (p)
UpdateDialogSize(p);
break;
case WM_SETFOCUS:
if (p->Focus && p->Focus->Control)
SetFocus(p->Focus->Control);
break;
case WM_DESTROY:
p->WndDialog = NULL;
break;
case WM_HSCROLL:
if (!lParam || !(GetWindowLong((HWND)lParam,GWL_STYLE) & (TBS_BOTH|TBS_NOTICKS|TBS_FIXEDLENGTH)))
HScroll(p,LOWORD(wParam),0);
else
{
i = (wincontrol*) GetWindowLong((HWND)lParam,GWL_USERDATA);
if (VALIDCONTROL(i))
{
WinControlFocus(p,i,1);
SetTrack(p,i,SendMessage((HWND)lParam,TBM_GETPOS,0,0));
}
}
break;
case WM_VSCROLL:
if (!lParam || !(GetWindowLong((HWND)lParam,GWL_STYLE) & (TBS_BOTH|TBS_NOTICKS|TBS_FIXEDLENGTH)))
VScroll(p,LOWORD(wParam),0);
break;
case WM_KEYDOWN:
if (wParam == VK_ESCAPE)
WinClose(p);
if (p->ScrollV && wParam == VK_UP)
VScroll(p,SB_LINEUP,0);
if (p->ScrollV && wParam == VK_DOWN)
VScroll(p,SB_LINEDOWN,0);
if (p->ScrollH && wParam == VK_LEFT)
HScroll(p,SB_LINEUP,0);
if (p->ScrollH && wParam == VK_RIGHT)
HScroll(p,SB_LINEDOWN,0);
break;
#if defined(TARGET_WINCE)
case WM_CTLCOLOREDIT:
SetBkColor((HDC)wParam,GetSysColor(COLOR_BTNFACE));
return (LRESULT) GetSysColorBrush(COLOR_BTNFACE);
#endif
case WM_CTLCOLORSTATIC:
i = (wincontrol*)GetWindowLong((HWND)lParam,GWL_USERDATA);
if (i && p->Focus && p->Focus == i->Ref)
{
if (p->Smartphone)
{
SetTextColor((HDC)wParam,GetSysColor(COLOR_HIGHLIGHTTEXT));
SetBkColor((HDC)wParam,GetSysColor(COLOR_HIGHLIGHT));
return (LRESULT) GetSysColorBrush(COLOR_HIGHLIGHT);
}
SetTextColor((HDC)wParam,0xC00000);
}
SetBkColor((HDC)wParam,GetSysColor(DIALOG_COLOR));
return (LRESULT) GetSysColorBrush(DIALOG_COLOR);
}
return DefWindowProc(Wnd,Msg,wParam,lParam);
}
static void WinScroll(win* p,int dx,int dy)
{
ScrollWindowEx(p->WndDialog, dx, dy, NULL, NULL, NULL, NULL, SW_SCROLLCHILDREN | SW_ERASE | SW_INVALIDATE );
}
static void WinUpdateScroll(win* p)
{
SCROLLINFO Scroll;
POINT Offset;
RECT Page;
int MaxWidth,MinWidth;
int MaxHeight,MinHeight;
HWND Child;
int XVScroll = GetSystemMetrics(SM_CXVSCROLL);
int YHScroll = GetSystemMetrics(SM_CYHSCROLL);
if (p->InUpdateScroll || p->OwnDialogSize)
return;
p->InUpdateScroll = 1;
Offset.x = Offset.y = 0;
ClientToScreen(p->WndDialog,&Offset);
GetClientRect(p->WndDialog,&Page);
if (p->ScrollV)
Page.right += XVScroll;
if (p->ScrollH)
Page.bottom += YHScroll;
MinWidth = 0;
MinHeight = 0;
MaxWidth = 0;
MaxHeight = 0;
Child = GetWindow(p->WndDialog,GW_CHILD);
while (Child && IsWindow(Child))
{
RECT r;
GetWindowRect(Child,&r);
r.left -= Offset.x;
r.right -= Offset.x;
r.top -= Offset.y;
r.bottom -= Offset.y;
r.bottom += YHScroll;
if (r.left < MinWidth) MinWidth = r.left;
if (r.right > MaxWidth) MaxWidth = r.right;
if (r.top < MinHeight) MinHeight = r.top;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -