前段時間對TCPMP程序進行了研究,花了點時間把TCPMP程序的UI修改成了自已想要的樣子,現對UI的修改方法簡單介紹下:
網上有文章對於TCPMP程序在ARMV4下的編譯方法和程序的結構介紹比較詳細,但對於inteface方面的修改方法講得並不多.
修改TCPMP界面基本上有兩種方法:
1) 建立自已的工程,把TCPMP下的lib移植到這個工程裏,這樣界面的修改比較靈活,但是工作量比較大;
2) 直接在TCPMP工程裏修改interface,這樣工作量相對比較小,但是UI的修改受了定的約束, 沒有前種方法靈活.
本人所修改的UI是按照第二種方法來做的.主要是對win_win32.c文件和inteface.c 文件進行修改.
首先,我們來看看win_win32.c文件裏的Win_Init()函數,這個函數可以看作是TCPMP UI部分的一個入口,在這個函數裏註冊了兩個窗口類,WinClass和DialogClass.另外還調用了其它控件的初始化函數,下面是這個函數的代碼.
view plaincopy to clipboardprint?
void Win_Init()
{
HMODULE Module = Context()->LoadModule;
if (!Module) Module = GetModuleHandle(NULL);
InitCommonControls();
WidcommAudio_Init();
stprintf_s(WinClassName,TSIZEOF(WinClassName),T("%s_Win"),Context()->ProgramName);
memset(&WinClass,0,sizeof(WinClass));
WinClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
WinClass.lpfnWndProc = Proc;
WinClass.cbClsExtra = 0;
WinClass.cbWndExtra = 0;
WinClass.hInstance = Module;
WinClass.hIcon = LoadIcon (GetModuleHandle(NULL), MAKEINTRESOURCE(WIN_ICON));
WinClass.hCursor = WinCursorArrow();
WinClass.hbrBackground =NULL;
WinClass.lpszMenuName = 0;
WinClass.lpszClassName = WinClassName;
RegisterClass(&WinClass);
#if 1
memset(&DialogClass,0,sizeof(DialogClass));
DialogClass.style = CS_HREDRAW | CS_VREDRAW;
DialogClass.lpfnWndProc = DialogProc;
DialogClass.cbClsExtra = 0;
DialogClass.cbWndExtra = 0;
DialogClass.hInstance = Module;
DialogClass.hCursor = WinCursorArrow();
#if defined(TARGET_WINCE)
DialogClass.hbrBackground = GetSysColorBrush(COLOR_STATIC);//
#else
DialogClass.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
#endif
DialogClass.lpszMenuName = 0;
DialogClass.lpszClassName = T("DialogBase");
RegisterClass(&DialogClass);
#endif
memset(&FontCache,0,sizeof(FontCache));
#if defined(TARGET_WINCE)
if (Context()->ProgramId >= 3 && !QueryAdvanced(ADVANCED_OLDSHELL))
{
AygShell = LoadLibrary(T("aygshell.dll"));
*(FARPROC*)&FuncSHCreateMenuBar = GetProcAddress(AygShell,T("SHCreateMenuBar"));
*(FARPROC*)&FuncSHInitDialog = GetProcAddress(AygShell,T("SHInitDialog"));
*(FARPROC*)&FuncSHFullScreen = GetProcAddress(AygShell,T("SHFullScreen"));
*(FARPROC*)&FuncSHHandleWMActivate = GetProcAddress(AygShell,MAKEINTRESOURCE(84));
*(FARPROC*)&FuncSHHandleWMSettingChange = GetProcAddress(AygShell,MAKEINTRESOURCE(83));
*(FARPROC*)&FuncSHSendBackToFocusWindow = GetProcAddress(AygShell,MAKEINTRESOURCE(97));
}
CoreDLL = LoadLibrary(T("coredll.dll"));
*(FARPROC*)&FuncUnregisterFunc1 = GetProcAddress(CoreDLL,T("UnregisterFunc1"));
*(FARPROC*)&FuncAllKeys = GetProcAddress(CoreDLL,T("AllKeys"));
*(FARPROC*)&FuncSipShowIM = GetProcAddress(CoreDLL,T("SipShowIM"));
*(FARPROC*)&FuncSipGetInfo = GetProcAddress(CoreDLL,T("SipGetInfo"));
#endif
NodeRegisterClass(&Win);
QueryKey_Init();
OpenFile_Init();
Interface_Init();
PlaylistWin_Init();
PlaylistNewWin_Init();
}
void Win_Init()
{
HMODULE Module = Context()->LoadModule;
if (!Module) Module = GetModuleHandle(NULL);
InitCommonControls();
WidcommAudio_Init();
stprintf_s(WinClassName,TSIZEOF(WinClassName),T("%s_Win"),Context()->ProgramName);
memset(&WinClass,0,sizeof(WinClass));
WinClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
WinClass.lpfnWndProc = Proc;
WinClass.cbClsExtra = 0;
WinClass.cbWndExtra = 0;
WinClass.hInstance = Module;
WinClass.hIcon = LoadIcon (GetModuleHandle(NULL), MAKEINTRESOURCE(WIN_ICON));
WinClass.hCursor = WinCursorArrow();
WinClass.hbrBackground =NULL;
WinClass.lpszMenuName = 0;
WinClass.lpszClassName = WinClassName;
RegisterClass(&WinClass);
#if 1
memset(&DialogClass,0,sizeof(DialogClass));
DialogClass.style = CS_HREDRAW | CS_VREDRAW;
DialogClass.lpfnWndProc = DialogProc;
DialogClass.cbClsExtra = 0;
DialogClass.cbWndExtra = 0;
DialogClass.hInstance = Module;
DialogClass.hCursor = WinCursorArrow();
#if defined(TARGET_WINCE)
DialogClass.hbrBackground = GetSysColorBrush(COLOR_STATIC);//
#else
DialogClass.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
#endif
DialogClass.lpszMenuName = 0;
DialogClass.lpszClassName = T("DialogBase");
RegisterClass(&DialogClass);
#endif
memset(&FontCache,0,sizeof(FontCache));
#if defined(TARGET_WINCE)
if (Context()->ProgramId >= 3 && !QueryAdvanced(ADVANCED_OLDSHELL))
{
AygShell = LoadLibrary(T("aygshell.dll"));
*(FARPROC*)&FuncSHCreateMenuBar = GetProcAddress(AygShell,T("SHCreateMenuBar"));
*(FARPROC*)&FuncSHInitDialog = GetProcAddress(AygShell,T("SHInitDialog"));
*(FARPROC*)&FuncSHFullScreen = GetProcAddress(AygShell,T("SHFullScreen"));
*(FARPROC*)&FuncSHHandleWMActivate = GetProcAddress(AygShell,MAKEINTRESOURCE(84));
*(FARPROC*)&FuncSHHandleWMSettingChange = GetProcAddress(AygShell,MAKEINTRESOURCE(83));
*(FARPROC*)&FuncSHSendBackToFocusWindow = GetProcAddress(AygShell,MAKEINTRESOURCE(97));
}
CoreDLL = LoadLibrary(T("coredll.dll"));
*(FARPROC*)&FuncUnregisterFunc1 = GetProcAddress(CoreDLL,T("UnregisterFunc1"));
*(FARPROC*)&FuncAllKeys = GetProcAddress(CoreDLL,T("AllKeys"));
*(FARPROC*)&FuncSipShowIM = GetProcAddress(CoreDLL,T("SipShowIM"));
*(FARPROC*)&FuncSipGetInfo = GetProcAddress(CoreDLL,T("SipGetInfo"));
#endif
NodeRegisterClass(&Win);
QueryKey_Init();
OpenFile_Init();
Interface_Init();
PlaylistWin_Init();
PlaylistNewWin_Init();
}
在此函數中我們需要注意 WinClass.lpfnWndProc= Proc; Proc是消息處理函數名.實際上所有的消息處理都是在static LRESULT CALLBACK Proc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)函數裏完成的.
下面對此函數中比較重點的消息作下說明:
WM_CREATE消息裏主要是建立播放的窗口;
WM_PAINT消息裏可以貼上UI的背景圖片,這樣使UI看上去比較美觀.貼圖部分程序如下:
view plaincopy to clipboardprint?
case WM_PAINT:
{
hdc = BeginPaint(Wnd,&Paint);
MainBkGnd = LoadBitmap(p->Module,MAKEINTRESOURCE(IDB_MAIN_BKG));
MemDC = CreateCompatibleDC(hdc);
bmpOld = (HBITMAP)SelectObject(MemDC,MainBkGnd);
BitBlt(hdc,0,0,LCD_XSIZE,LCD_YSIZE,MemDC,0,0,SRCCOPY);
SelectObject(MemDC,bmpOld);
DeleteObject(bmpOld);
DeleteDC(MemDC);
EndPaint(Wnd,&Paint);
}
break;
case WM_PAINT:
{
hdc = BeginPaint(Wnd,&Paint);
MainBkGnd = LoadBitmap(p->Module,MAKEINTRESOURCE(IDB_MAIN_BKG));
MemDC = CreateCompatibleDC(hdc);
bmpOld = (HBITMAP)SelectObject(MemDC,MainBkGnd);
BitBlt(hdc,0,0,LCD_XSIZE,LCD_YSIZE,MemDC,0,0,SRCCOPY);
SelectObject(MemDC,bmpOld);
DeleteObject(bmpOld);
DeleteDC(MemDC);
EndPaint(Wnd,&Paint);
}
break;
WM_COMMAND消息是所有菜單 ,按鈕等點擊後處理的入口點,具體的實現在interface.c裏的static int Command(intface* p,int Cmd)函數裏來做處理。如播放,暫停,前一首,下一首等.還有其它的一些消息處理在此不做介紹了.
Interface.c的程序結構和win_win32.c 基本差不多,其中最主要的也是static bool_t Proc(intface* p, int Msg, uint32_t wParam, uint32_t lParam, int* Result)函數對消息的處理.在此函數的WM_CREATE消息裏可以建立起各種控件的消息處理.然後分別在各控件的消息處理函數裏通過上面貼bitmap圖片的方式來改變控件的外觀.
其實對於TCPMP程序UI部分的修改,最主要的還是要讀懂源代碼.在讀懂源代碼的基礎上再結合Win32程序的結構來修改界面還是比較容易的.
下面Show一下我做的界面吧!
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/ceFighter/archive/2009/04/17/4086332.aspx
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/ceFighter/archive/2009/04/17/4086332.aspx