📄 win_win32.c
字号:
if (r.bottom > MaxHeight) MaxHeight = r.bottom;
Child = GetWindow(Child,GW_HWNDNEXT);
}
Scroll.cbSize = sizeof(Scroll);
Scroll.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
if (MaxHeight < Page.bottom)
MaxHeight = Page.bottom-1;
p->ScrollV = MaxHeight-MinHeight > Page.bottom;
Scroll.nMin = MinHeight;
Scroll.nMax = MaxHeight;
Scroll.nPos = 0;
Scroll.nPage = Page.bottom;
SetScrollInfo(p->WndDialog,SB_VERT,&Scroll,TRUE);
if (p->ScrollV)
Page.right -= XVScroll;
if (MaxWidth < Page.right)
MaxWidth = Page.right-1;
p->ScrollH = MaxWidth-MinWidth > Page.right;
Scroll.nMin = MinWidth;
Scroll.nMax = MaxWidth;
Scroll.nPos = 0;
Scroll.nPage = Page.right;
SetScrollInfo(p->WndDialog,SB_HORZ,&Scroll,TRUE);
p->InUpdateScroll = 0;
}
static void VScroll(win* p,int Cmd,int Delta)
{
int Pos;
SCROLLINFO Scroll;
Scroll.cbSize = sizeof(Scroll);
Scroll.fMask = SIF_ALL;
GetScrollInfo(p->WndDialog, SB_VERT, &Scroll);
Pos = Scroll.nPos;
if (Delta)
Scroll.nPos += Delta;
else
switch (Cmd)
{
case SB_TOP:
Scroll.nPos = Scroll.nMin;
break;
case SB_BOTTOM:
Scroll.nPos = Scroll.nMax;
break;
case SB_LINEUP:
Scroll.nPos -= WinUnitToPixelY(p,16);
break;
case SB_LINEDOWN:
Scroll.nPos += WinUnitToPixelY(p,16);
break;
case SB_PAGEUP:
Scroll.nPos -= Scroll.nPage;
break;
case SB_PAGEDOWN:
Scroll.nPos += Scroll.nPage;
break;
case SB_THUMBTRACK:
Scroll.nPos = Scroll.nTrackPos;
break;
default:
break;
}
Scroll.fMask = SIF_POS;
SetScrollInfo(p->WndDialog, SB_VERT, &Scroll, TRUE);
GetScrollInfo(p->WndDialog, SB_VERT, &Scroll);
if (Scroll.nPos != Pos)
WinScroll(p,0,Pos - Scroll.nPos);
}
static void HScroll(win* p,int Cmd,int Delta)
{
int Pos;
SCROLLINFO Scroll;
Scroll.cbSize = sizeof(Scroll);
Scroll.fMask = SIF_ALL;
GetScrollInfo(p->WndDialog, SB_HORZ, &Scroll);
Pos = Scroll.nPos;
if (Delta)
Scroll.nPos += Delta;
else
switch (Cmd)
{
case SB_TOP:
Scroll.nPos = Scroll.nMin;
break;
case SB_BOTTOM:
Scroll.nPos = Scroll.nMax;
break;
case SB_LINEUP:
Scroll.nPos -= WinUnitToPixelX(p,16);
break;
case SB_LINEDOWN:
Scroll.nPos += WinUnitToPixelX(p,16);
break;
case SB_PAGEUP:
Scroll.nPos -= Scroll.nPage;
break;
case SB_PAGEDOWN:
Scroll.nPos += Scroll.nPage;
break;
case SB_THUMBTRACK:
Scroll.nPos = Scroll.nTrackPos;
break;
default:
break;
}
Scroll.fMask = SIF_POS;
SetScrollInfo(p->WndDialog, SB_HORZ, &Scroll, TRUE);
GetScrollInfo(p->WndDialog, SB_HORZ, &Scroll);
if (Scroll.nPos != Pos)
WinScroll(p,Pos - Scroll.nPos,0);
}
static bool_t OwnWindow(HWND Wnd)
{
tchar_t ClassName[64];
for (;Wnd;Wnd=GetParent(Wnd))
{
GetClassName(Wnd,ClassName,64);
if (tcscmp(ClassName,WinClass.lpszClassName)==0 ||
tcscmp(ClassName,T("VolumeBack"))==0)
return 1;
}
return 0;
}
void ForwardMenuButtons(win* p,int Msg,uint32_t wParam,uint32_t lParam)
{
#if defined(TARGET_WINCE)
if (p->WndTB && (wParam == VK_F1 || wParam == VK_F2) &&
(QueryPlatform(PLATFORM_TYPENO) == TYPE_POCKETPC ||
QueryPlatform(PLATFORM_TYPENO) == TYPE_SMARTPHONE))
{
if (Msg == WM_KEYDOWN && !(lParam & (1<<30)))
{
PostMessage(p->WndTB,WM_HOTKEY,0,MAKELPARAM(0,wParam));
PostMessage(p->WndTB,WM_HOTKEY,0,MAKELPARAM(0x1000,wParam));
}
}
#endif
}
static LRESULT CALLBACK Proc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
int Result = 0;
win* p = (win*)GetWindowLong(Wnd,GWL_USERDATA);
switch (Msg)
{
#if defined(TARGET_WINCE)
case WM_HOTKEY:
if (p->Parent && HIWORD(lParam)==VK_ESCAPE)
{
HWND Focus = GetFocus();
wincontrol* i = (wincontrol*)GetWindowLong(Focus,GWL_USERDATA);
if (FuncSHSendBackToFocusWindow && ((VALIDCONTROL(i) && i->Editor) || (!VALIDCONTROL(i) && i)))
FuncSHSendBackToFocusWindow(Msg,wParam,lParam);
else
{
p->HotKeyEscape = !p->HotKeyEscape;
if (!p->HotKeyEscape)
PostMessage(p->Wnd,WM_CLOSE,0,0);
}
return 0;
}
break;
#endif
case WM_CREATE:
p = (win*)((CREATESTRUCT*)lParam)->lpCreateParams;
p->Wnd = Wnd;
p->Module = ((CREATESTRUCT*)lParam)->hInstance;
p->Result = 1;
p->Focus = NULL;
p->Closed = 0;
UpdateDPI(p);
#if defined(TARGET_WINCE)
p->Activate = malloc(sizeof(SHACTIVATEINFO));
if (p->Activate)
{
memset(p->Activate,0,sizeof(SHACTIVATEINFO));
((SHACTIVATEINFO*)p->Activate)->cbSize = sizeof(SHACTIVATEINFO);
}
#endif
if (p->Proc)
p->Proc(p,MSG_PREPARE,0,0,&Result);
CreateToolBar(p);
SetWindowLong(Wnd,GWL_USERDATA,(LONG)p); // only after CreateToolBar (WM_MOVE)
if (p->Flags & WIN_DIALOG)
{
RECT r;
GetClientRect(p->Wnd,&r);
CreateWindow(DialogClass.lpszClassName,NULL,WS_CLIPCHILDREN|WS_CHILD|WS_VISIBLE,
0,p->ToolBarHeight,r.right,r.bottom-p->ToolBarHeight,p->Wnd,NULL,DialogClass.hInstance,p);
}
if (p->Init)
p->Init(p);
if (!p->Focus)
WinNext(p,0);
break;
case WM_CLOSE:
p->Closed = 1;
p->Focus = NULL;
SetFocus(NULL);
if (p->Done)
p->Done(p);
if (p->WndDialog)
ShowWindow(p->WndDialog,SW_HIDE);
WinClear(p);
if (p->Parent)
{
EnableWindow(p->Parent->Wnd,TRUE);
p->Parent->Child = NULL;
SetForegroundWindow(p->Parent->Wnd);
DestroyWindow(p->Wnd);
}
break;
case WM_SETFOCUS:
if (p->WndDialog)
SetFocus(p->WndDialog);
if (!p->Parent)
WidcommAudio_Wnd(p->Wnd);
break;
case WM_SIZE:
if (p)
{
RECT r;
GetClientRect(p->Wnd,&r);
if (p->ToolBarHeight)
MoveWindow(p->WndTB,0,0,r.right,p->ToolBarHeight,TRUE);
if (p->WndDialog && !p->OwnDialogSize)
MoveWindow(p->WndDialog,0,p->ToolBarHeight,r.right,r.bottom-p->ToolBarHeight,TRUE);
}
break;
case WM_DESTROY:
WinSetFullScreen(p,0);
DestroyToolBar(p);
if (p->Menu3)
DestroyMenu(p->Menu3);
p->Wnd = NULL;
p->WndTB = NULL;
memset(p->Menu2,0,sizeof(p->Menu2));
break;
case WM_COMMAND:
if (LOWORD(wParam) == WIN_A)
wParam = p->WinCmd[0];
if (LOWORD(wParam) == WIN_B)
wParam = p->WinCmd[1];
if (LOWORD(wParam) == IDOK)
wParam = PLATFORM_OK;
if (p->Command && p->Command(p,LOWORD(wParam))==ERR_NONE)
return 0;
if (LOWORD(wParam) == PLATFORM_OK ||
LOWORD(wParam) == PLATFORM_DONE ||
LOWORD(wParam) == PLATFORM_CANCEL)
{
WinClose(p);
return 0;
}
break;
case WM_ACTIVATE:
if (LOWORD(wParam)!=WA_INACTIVE)
{
if (WidcommAudio_SkipActivate())
return 0;
if (!p->Parent)
WidcommAudio_Wnd(p->Wnd);
if (p->Child)
{
SetForegroundWindow(p->Child->Wnd);
return 0;
}
}
#if defined(TARGET_WINCE)
if (FuncSHHandleWMActivate && p->Activate && !TaskBarHidden)
FuncSHHandleWMActivate(Wnd, wParam, lParam, p->Activate, FALSE);
#endif
break;
case WM_SETTINGCHANGE:
#if defined(TARGET_WINCE)
if (FuncSHHandleWMSettingChange && p->Activate && !TaskBarHidden)
FuncSHHandleWMSettingChange(Wnd, wParam, lParam, p->Activate);
#endif
UpdateDPI(p);
break;
}
if (p)
{
if (p->Proc && p->Proc(p,Msg,wParam,lParam,&Result))
return Result;
if (Msg == WM_ACTIVATE && !OwnWindow((HWND)lParam))
{
if (LOWORD(wParam)==WA_INACTIVE)
{
bool_t b = 1;
node* Player = Context()->Player;
if (Player && Main && !Main->Closed)
Player->Set(Player,PLAYER_BACKGROUND,&b,sizeof(b));
#if defined(TARGET_WINCE)
if (TaskBarHidden)
{
DIASet(DIA_TASKBAR,DIA_TASKBAR);
TaskBarHidden = 1;
}
#endif
}
else
{
bool_t b = 0;
node* Player = Context()->Player;
if (Player && Main && !Main->Closed)
Player->Set(Player,PLAYER_BACKGROUND,&b,sizeof(b));
#if defined(TARGET_WINCE)
if (TaskBarHidden)
{
TaskBarHidden = 0;
DIASet(0,DIA_TASKBAR);
}
#endif
}
}
#if defined(TARGET_WINCE)
if (Msg == WM_CREATE && !p->AygShellTB && ((p->Flags & WIN_DIALOG) || GetSystemMetrics(SM_CXSCREEN)>240))
CommandBar_AddAdornments(p->WndTB,p->NeedOK ? CMDBAR_OK:0,0);
#endif
if (p->WndDialog && (Msg == WM_CREATE || Msg == WM_SIZE))
WinUpdateScroll(p);
}
return DefWindowProc(Wnd,Msg,wParam,lParam);
}
static void HandleMessage(win* p,MSG* Msg)
{
int Result;
#if defined(TARGET_WINCE)
if (Msg->message == WM_HIBERNATE)
{
if (AvailMemory() < 256*1024) // don't mess up format_base buffering...
NodeHibernate();
}
#endif
if (Msg->message >= WM_APP + 0x200 &&
Msg->message <= WM_APP + 0x220)
{
// send to application window
win* Appl=p;
while (Appl->Parent)
Appl=Appl->Parent;
if (Appl->Proc(Appl,Msg->message,Msg->wParam,Msg->lParam,&Result))
return;
}
if (Msg->message == WM_KEYDOWN)
{
if (p->CaptureKeys && p->Proc && p->Proc(p,Msg->message,Msg->wParam,Msg->lParam,&Result))
return;
if (p->Focus)
{
int Type;
switch (Msg->wParam)
{
case VK_LEFT:
case VK_RIGHT:
if (!p->Focus->ListView)
{
Type = GetDataDefType(p->Focus);
if (!Type || Type == TYPE_BOOL || Type == TYPE_RESET || Type == TYPE_HOTKEY)
{
SendMessage(p->WndDialog,Msg->message,Msg->wParam,Msg->lParam);
return;
}
}
break;
case VK_RETURN:
Type = GetDataDefType(p->Focus);
if (Type == TYPE_BOOL || Type == TYPE_RESET || Type == TYPE_HOTKEY)
{
SendMessage(p->Focus->Control,BM_CLICK,0,0);
return;
}
if (p->Focus->ComboBox && !p->ComboOpen)
{
SendMessage(p->Focus->Control,CB_SHOWDROPDOWN,1,0);
return;
}
if (Type == TYPE_STRING)
{
SendMessage(p->WndDialog,Msg->message,Msg->wParam,Msg->lParam);
return;
}
break;
case VK_DOWN:
case VK_UP:
if (!p->ComboOpen && !p->Focus->ListView)
{
WinNext(p,Msg->wParam==VK_UP);
return;
}
break;
case VK_TAB:
WinNext(p,GetKeyState(VK_SHIFT)<0);
return;
}
}
}
TranslateMessage(Msg);
DispatchMessage(Msg);
}
int WinPopupClass(int Class,win* Parent)
{
int Result = 0;
node* p = NodeCreate(Class);
if (p && NodeIsClass(p->Class,WIN_CLASS))
{
Result = ((win*)p)->Popup((win*)p,Parent);
NodeDelete(p);
}
return Result;
}
static int Popup(win* p,win* Parent)
{
HWND Wnd;
MSG Msg;
int Style = WS_VISIBLE;
int ExStyle = 0;
int x,y;
int Width,Height;
int Priority;
// we need higher priority in main window for better user interface responses
// but open dialog and other parts can't have that, because of some buggy keyboard drivers...
Priority = ThreadPriority(NULL,Parent?0:-1);
p->Result = 0;
p->Parent = Parent;
p->BitmapNo = 0;
p->AygShellTB = 0;
#if defined(TARGET_WINCE)
if (AygShell && Parent)
ExStyle |= WS_EX_CAPTIONOKBTN;
if (Parent)
Style |= WS_POPUP;
{
RECT r;
GetWorkArea(p,&r);
x = r.left;
y = r.top;
Width = r.right - r.left;
Height = r.bottom - r.top;
}
#else
Style |= WS_OVERLAPPEDWINDOW;
y = x = CW_USEDEFAULT;
Width = WinUnitToPixelX(p,p->WinWidth);
Height = WinUnitToPixelY(p,p->WinHeight);
#endif
Wnd = CreateWindowEx(ExStyle,WinClass.lpszClassName,LangStr(p->Node.Class,NODE_NAME),Style,x,y,Width,Height,
Parent?Parent->Wnd:NULL,NULL,WinClass.hInstance,p);
if (Wnd)
{
if (p->Parent)
{
p->Parent->Child = p;
EnableWindow(p->Parent->Wnd,0);
}
else
Main = p;
while (p->Wnd && GetMessage(&Msg, NULL, 0, 0))
HandleMessage(p,&Msg);
if (Main == p)
Main = NULL;
}
ThreadPriority(NULL,Priority);
return p->Result;
}
static int Create(win* p)
{
UpdateDPI(p); // with NULL Wnd, because we need ScreenWidth
p->Smartphone = QueryPlatform(PLATFORM_TYPENO) == TYPE_SMARTPHONE;
p->Popup = Popup;
p->Closed = 1;
return ERR_NONE;
}
static const nodedef Win
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -