📄 win_win32.c
字号:
/*****************************************************************************
*
* This program is free software ; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: win_win32.c 623 2006-02-01 13:19:15Z picard $
*
* The Core Pocket Media Player
* Copyright (c) 2004-2005 Gabor Kovacs
*
****************************************************************************/
#include "../../common/common.h"
#include "../win.h"
#include "widcommaudio.h"
#include "querykey_win32.h"
#include "openfile_win32.h"
#include "playlst.h"
#include "interface.h"
#if defined(TARGET_WINCE) || defined(TARGET_WIN32)
#define WIN32_LEAN_AND_MEAN
#ifndef STRICT
#define STRICT
#endif
#include <windows.h>
#if _MSC_VER > 1000
#pragma warning(disable : 4201)
#endif
#include <commctrl.h>
#include <shellapi.h>
#include "resource.h"
#define MAXFONTSIZE 64
static HFONT FontCache[MAXFONTSIZE][2];
static WNDCLASS WinClass;
static WNDCLASS DialogClass;
static tchar_t WinClassName[64];
static win* Main = NULL;
#ifndef GCL_HMODULE
#define GCL_HMODULE (-16)
#endif
#ifndef UDS_EXPANDABLE
#define UDS_EXPANDABLE 0x0200
#endif
#if defined(TARGET_WINCE)
#define DIALOG_COLOR COLOR_STATIC
#else
#define DIALOG_COLOR COLOR_BTNFACE
#define MOD_KEYUP 0
#endif
#define VALIDCONTROL(i) ((int)(i) & ~0xFFFF)
#define TRACKMAX 30000
#define TRACKTHUMB 9
static BOOL (WINAPI* FuncUnregisterFunc1)( int Flags,int HoyKey ) = NULL;
static BOOL (WINAPI* FuncAllKeys)( int State ) = NULL;
#define TOOLBAR_ID 1000
#if !defined(TARGET_WINCE)
#define TBSTYLE_EX_MIXEDBUTTONS 0x00000008
#ifndef BTNS_SHOWTEXT
#define BTNS_SHOWTEXT 0x40
#endif
#else
#define BTNS_SHOWTEXT 0
#endif
static const menudef* MenuDef(win* Win,const menudef* p,bool_t Popup,void** Menu)
{
int Level = p->Level;
if (!*Menu)
*Menu = Popup ? CreatePopupMenu() : CreateMenu();
while (p->Level==Level && Level>=0)
{
bool_t Skip = 0;
if (p->Id==-1)
{
if (!Win->MenuSmall && !Skip)
AppendMenu(*Menu,MF_SEPARATOR,0,NULL);
++p;
}
else
{
tchar_t s[256];
int Flags = MF_STRING;
int Id = p->Id;
tcscpy_s(s,TSIZEOF(s),LangStr(p->Class,p->Id));
if (p->Class == PLATFORM_ID)
{
if (p->Level==0 && p->Id == PLATFORM_CANCEL && Win->TitleCancel)
{
++p;
continue;
}
if (p->Id == PLATFORM_OK)
{
Win->NeedOK = 1;
if (Win->TitleOK)
{
++p;
continue;
}
}
if (p->Id == PLATFORM_DONE)
{
Win->NeedOK = 1;
if (Win->TitleDone)
{
++p;
continue;
}
}
}
++p;
if (p->Level > Level)
{
if (((p[-1].Flags & MENU_SMALL) && !Win->MenuSmall) ||
((p[-1].Flags & MENU_NOTSMALL) && Win->MenuSmall))
{
if (p[-1].Flags & MENU_GRAYED)
{
AppendMenu(*Menu,Flags,Id,s);
EnableMenuItem(*Menu,Id,MF_GRAYED|MF_BYCOMMAND);
}
// skip
p = MenuDef(Win,p,1,Menu);
continue;
}
else
if (p[-1].Flags & MENU_GRAYED)
{
int i = tcslen(s);
if (i && s[i-1]==':')
s[i-1] = 0;
}
Id = 0;
p = MenuDef(Win,p,1,(HMENU*)&Id);
Flags |= MF_POPUP;
}
if (!Skip)
{
AppendMenu(*Menu,Flags,Id,s);
if (!(Flags & MF_POPUP) && (p[-1].Flags & MENU_GRAYED))
EnableMenuItem(*Menu,Id,MF_GRAYED|MF_BYCOMMAND);
}
else
{
if (Flags & MF_POPUP)
DestroyMenu((HMENU)Id);
}
}
}
return p;
}
#if defined(TARGET_WINCE)
#define SIPF_OFF 0x00000000
#define SIPF_ON 0x00000001
typedef struct SHACTIVATEINFO
{
DWORD cbSize;
HWND hwndLastFocus;
UINT fSipUp:1;
UINT fSipOnDeactivation:1;
UINT fActive:1;
UINT fReserved:29;
} SHACTIVATEINFO;
#define SHMBOF_NODEFAULT 0x00000001
#define SHMBOF_NOTIFY 0x00000002
#define SHCMBM_GETSUBMENU (WM_USER + 401)
#define SHCMBM_GETMENU (WM_USER + 402)
#define SHCMBM_OVERRIDEKEY (WM_USER + 403)
#define SHCMBF_EMPTYBAR 0x0001
#define SHCMBF_HIDDEN 0x0002
#define SHCMBF_HIDESIPBUTTON 0x0004
#define SHCMBF_COLORBK 0x0008
#define SHCMBF_HMENU 0x0010
typedef struct SHMENUBARINFO
{
DWORD cbSize;
HWND hwndParent;
DWORD dwFlags;
UINT nToolBarId;
HINSTANCE hInstRes;
int nBmpId;
int cBmpImages;
HWND hwndMB;
// COLORREF clrBk; //be as compatible as possible
} SHMENUBARINFO;
#define SHIDIM_FLAGS 0x0001
#define SHIDIF_DONEBUTTON 0x0001
#define SHIDIF_SIZEDLG 0x0002
#define SHIDIF_SIZEDLGFULLSCREEN 0x0004
#define SHIDIF_SIPDOWN 0x0008
#define SHIDIF_FULLSCREENNOMENUBAR 0x0010
#define SHIDIF_EMPTYMENU 0x0020
typedef struct SHINITDLGINFO
{
DWORD dwMask;
HWND hDlg;
DWORD dwFlags;
} SHINITDLGINFO;
#define SPI_GETSIPINFO 225
#define SPI_APPBUTTONCHANGE 228
typedef struct SIPINFO
{
DWORD cbSize;
DWORD fdwFlags;
RECT rcVisibleDesktop;
RECT rcSipRect;
DWORD dwImDataSize;
void *pvImData;
} SIPINFO;
#define SHFS_SHOWTASKBAR 0x0001
#define SHFS_HIDETASKBAR 0x0002
#define SHFS_SHOWSIPBUTTON 0x0004
#define SHFS_HIDESIPBUTTON 0x0008
#define SHFS_SHOWSTARTICON 0x0010
#define SHFS_HIDESTARTICON 0x0020
static HMODULE AygShell = NULL;
static HMODULE CoreDLL = NULL;
static BOOL (WINAPI* FuncSipGetInfo)(SIPINFO *pSipInfo) = NULL;
static BOOL (WINAPI* FuncSipShowIM)(DWORD) = NULL;
static BOOL (WINAPI* FuncSHCreateMenuBar)( SHMENUBARINFO *pmb ) = NULL;
static BOOL (WINAPI* FuncSHInitDialog)( SHINITDLGINFO *shdi ) = NULL;
static BOOL (WINAPI* FuncSHFullScreen)( HWND, DWORD ) = NULL;
static BOOL (WINAPI* FuncSHHandleWMActivate)( HWND, WPARAM, LPARAM, void*, DWORD ) = NULL;
static BOOL (WINAPI* FuncSHHandleWMSettingChange)(HWND, WPARAM, LPARAM, void*) = NULL;
static BOOL (WINAPI* FuncSHSendBackToFocusWindow)(UINT, WPARAM, LPARAM ) = NULL;
static bool_t HHTaskbarTop = 0;
static bool_t TaskBarHidden = 0;
void MergeRect(RECT* r,HWND Wnd)
{
if (Wnd)
{
RECT a;
GetWindowRect(Wnd,&a);
if (a.bottom == r->top)
r->top = a.top;
if (a.top == r->bottom)
r->bottom = a.bottom;
}
}
void GetWorkArea(win* p,RECT* r)
{
SystemParametersInfo(SPI_GETWORKAREA,0,r,0);
if (p->AygShellTB && p->WndTB)
{
RECT RectTB;
GetWindowRect(p->WndTB, &RectTB);
if (r->bottom > RectTB.top)
r->bottom = RectTB.top;
}
if (TaskBarHidden)
{
MergeRect(r,FindWindow(T("HHTaskbar"),NULL));
MergeRect(r,FindWindow(T("Tray"),NULL));
}
}
void DIASet(int State,int Mask)
{
if ((Mask & DIA_SIP) && FuncSipShowIM)
FuncSipShowIM((State & DIA_SIP)?SIPF_ON:SIPF_OFF);
if (Mask & DIA_TASKBAR)
{
bool_t Hidden = !(State & DIA_TASKBAR);
if (Hidden != TaskBarHidden)
{
win* p;
HWND WndTaskbar = FindWindow(T("HHTaskbar"),NULL);
HWND WndTray = FindWindow(T("Tray"),NULL); //for smartphone
TaskBarHidden = Hidden;
if (WndTaskbar)
ShowWindow(WndTaskbar,Hidden ? SW_HIDE:SW_SHOWNA);
if (WndTray)
ShowWindow(WndTray,Hidden ? SW_HIDE:SW_SHOWNA);
for (p=Main;p;p=p->Child)
{
if (FuncSHFullScreen)
FuncSHFullScreen(p->Wnd,Hidden ? SHFS_HIDETASKBAR : SHFS_SHOWTASKBAR);
if (!p->FullScreen)
{
RECT r;
GetWorkArea(p,&r);
SetWindowPos(p->Wnd,NULL, r.left, r.top, r.right-r.left, r.bottom-r.top, SWP_NOZORDER);
}
else
{
p->SaveScreen.x = GetSystemMetrics(SM_CXSCREEN);
p->SaveScreen.y = GetSystemMetrics(SM_CYSCREEN);
GetWorkArea(p,(RECT*)&p->SaveRect);
}
}
}
}
}
int DIAGet(int Mask)
{
int Value = 0;
if ((Mask & DIA_TASKBAR) && !TaskBarHidden)
Value |= DIA_TASKBAR;
if ((Mask & DIA_SIP) && FuncSipGetInfo)
{
SIPINFO Info;
Info.cbSize = sizeof(Info);
if (FuncSipGetInfo(&Info) && (Info.fdwFlags & SIPF_ON))
Value |= DIA_SIP;
}
return Value;
}
void WinSetFullScreen(win* p,bool_t State)
{
if (State != p->FullScreen)
{
// no need to hide HHTaskbar because we use TOPMOST and with aygshell we use SHFS_HIDETASKBAR
HWND WndTaskbar = FindWindow(T("HHTaskbar"),NULL);
HWND WndTray = FindWindow(T("Tray"),NULL); //for smartphone
DEBUG_MSG1(DEBUG_WIN,T("FULLSCREEN %d"),State);
p->FullScreen = State; // set flag before SetWindowPos so WM_SIZE,WM_MOVE has valid info
if (State)
{
HWND Mode;
if (FuncSHFullScreen)
{
Mode = HWND_TOP; //incoming calls on smartphones doesn't like topmost
FuncSHFullScreen(p->Wnd,SHFS_HIDETASKBAR);
FuncSHFullScreen(p->Wnd,SHFS_HIDESIPBUTTON);
}
else
{
Mode = HWND_TOPMOST;
if (WndTaskbar)
{
RECT r;
GetWindowRect(WndTaskbar,&r);
HHTaskbarTop = r.top == 0 && r.left == 0;
if (HHTaskbarTop)
ShowWindow(WndTaskbar,SW_HIDE); // old-style with pocketpc
}
}
if (p->WndTB)
ShowWindow(p->WndTB,SW_HIDE);
if (WndTray)
ShowWindow(WndTray,SW_HIDE);
p->SaveScreen.x = GetSystemMetrics(SM_CXSCREEN);
p->SaveScreen.y = GetSystemMetrics(SM_CYSCREEN);
GetWindowRect(p->Wnd,(RECT*)&p->SaveRect);
SetWindowPos(p->Wnd,Mode, 0, 0, p->SaveScreen.x,p->SaveScreen.y,0);
ShowCursor(FALSE);
SetKeyboardBacklight(0);
}
else
{
ShowCursor(TRUE);
SetKeyboardBacklight(1);
if (p->WndTB)
ShowWindow(p->WndTB,SW_SHOWNA);
p->SaveRect[2] += GetSystemMetrics(SM_CXSCREEN) - p->SaveScreen.x;
p->SaveRect[3] += GetSystemMetrics(SM_CYSCREEN) - p->SaveScreen.y;
SetWindowPos(p->Wnd,HWND_NOTOPMOST,p->SaveRect[0],p->SaveRect[1],
p->SaveRect[2]-p->SaveRect[0],p->SaveRect[3]-p->SaveRect[1],SWP_NOACTIVATE);
if (!TaskBarHidden)
{
if (FuncSHFullScreen)
FuncSHFullScreen(p->Wnd,SHFS_SHOWTASKBAR);
else
if (WndTaskbar && HHTaskbarTop)
ShowWindow(WndTaskbar,SW_SHOWNA); // old-style with pocketpc
}
if (WndTray && !TaskBarHidden)
ShowWindow(WndTray,SW_SHOWNA);
}
}
}
static void DestroyToolBar(win* p)
{
if (p->WndTB)
{
CommandBar_Destroy(p->WndTB);
p->WndTB = NULL;
}
}
void WinBitmap(win* p,int BitmapId16, int BitmapId32, int BitmapNum)
{
if (p->WndTB)
{
if (p->LogPixelSX >= 96*2)
p->BitmapNo = CommandBar_AddBitmap(p->WndTB,p->Module,BitmapId32,BitmapNum,32,32);
else
p->BitmapNo = CommandBar_AddBitmap(p->WndTB,p->Module,BitmapId16,BitmapNum,16,16);
}
}
static const menudef* SkipButtons(win* p,const menudef* i)
{
while (i->Level==0)
{
bool_t Skip = 0;
if (p->TitleOK && i->Class == PLATFORM_ID && i->Id == PLATFORM_OK)
{
p->NeedOK = 1;
Skip = 1;
}
if (p->TitleDone && i->Class == PLATFORM_ID && i->Id == PLATFORM_DONE)
{
p->NeedOK = 1;
Skip = 1;
}
if (!Skip)
break;
++i;
}
return i;
}
static void AddButton(win* p,int Pos,int Id,int Bitmap,tchar_t* Name,bool_t Check);
static void CreateToolBar(win* p)
{
int Ver = QueryPlatform(PLATFORM_VER);
RECT Rect,RectTB;
p->WndTB = NULL;
p->Menu3 = NULL;
memset(&p->Menu2,0,sizeof(p->Menu2));
p->AygShellTB = 0;
p->TitleCancel = p->Smartphone && (p->Flags & WIN_DIALOG);
p->TitleOK = p->TitleDone = !p->Smartphone && !TaskBarHidden && Ver<500;
p->NeedOK = 0;
if (FuncSHCreateMenuBar)
{
SHMENUBARINFO Info;
memset(&Info,0,sizeof(Info));
Info.cbSize = sizeof(Info);
if (p->Smartphone)
Info.cbSize += sizeof(COLORREF); //clrBk
Info.hwndParent = p->Wnd;
Info.nToolBarId = 0;
Info.hInstRes = p->Module;
Info.dwFlags = 0;
if (!p->MenuDef)
Info.dwFlags |= SHCMBF_EMPTYBAR;
else
{
const menudef* i = p->MenuDef;
int Mode = 0;
i = SkipButtons(p,i);
if (i->Level==0)
{
++i;
for (;i->Level>0;++i)
Mode |= 1; // submenu under first menu
}
i = SkipButtons(p,i);
if (i->Level==0)
{
++i;
for (;i->Level>0;++i)
Mode |= 2; // submenu under second menu
}
switch (Mode)
{
case 0: Info.nToolBarId = IDR_MENU00; break;
case 1: Info.nToolBarId = IDR_MENU10; break;
case 2: Info.nToolBarId = IDR_MENU01; break;
case 3: Info.nToolBarId = IDR_MENU11; break;
}
}
if (!(p->Flags & WIN_DIALOG))
Info.dwFlags |= SHCMBF_HIDESIPBUTTON;
FuncSHCreateMenuBar(&Info);
p->WndTB = Info.hwndMB;
p->ToolBarHeight = 0;
GetWindowRect(p->Wnd, &Rect);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -