2009年6月27日 星期六

Win32 拖曳Tree-View項目

處理Win32的Tree-View Item主要分為三個步驟。
  • 開始拖曳通知。
  • 拖曳中處理。
  • 拖曳結束。
底下對拖曳程序的每個階段作個簡介,並提供實作範例。


開始拖曳通知

當使用者開始拖曳(Drag)Tree-View Item時,Tree-View元件會經由WM_NOTIFY訊息發送一個TVN_BEGINDRAG通知給父視窗,這時應用便可以以這個通知得知使用者從什麼位置開始拖曳那一個Item,並開始進入拖曳程序。
case WM_NOTIFY:
switch (((LPNMHDR)lParam)->code)
{
case TVN_BEGINDRAG:
// ...由此進入拖曳程序
Main_OnBeginDrag();
break;
}
break;
Main_OnBeginDrag是應用程式定義的一個函式,主要的任務是設定好相關狀態表示進入拖曳程序,並由Tree-View取得一個暫時的ImageList元件,可以用來畫出拖曳中的Item。
void Main_OnBeginDrag(HWND hwndTV, LPNMTREEVIEW lpnmtv)
{
// 取得暫時的ImageList.
HIMAGELIST himl = TreeView_CreateDragImage(hwndTV, lpnmtv->itemNew.hItem);

// 開始進入拖曳.
ImageList_BeginDrag(himl, 0, 0, 0);
ImageList_DragEnter(hwndTV, lpnmtv->pt.x, lpnmtv->pt.x);

SetCapture(GetParent(hwndTV));
g_fDragging = TRUE;
}
拖曳中處理

當使用者以滑鼠左鍵開以拖曳物件時,Tree-View送出一個TVN_BEGINDRAG,接著應用程式需要處理WM_MOUSEMOVE訊息來反應使用者拖曳的動作,直到使用者將滑鼠按鍵放開產生一個WM_LBUTTONUP訊息時,才結束拖曳動作。附帶一提,如果使用者是以滑鼠右鍵開始拖曳物件,則產生的通知是TVB_BEGINRDRAG,並以對應的WM_RBUTTONUP訊息作結束訊號。
void Main_OnMouseMove(HWND hwndParent, HWND hwndTV, LONG xCur, LONG yCur)
{
if (!g_fDragging)
return;

// 更新滑鼠拖曳的座標.
POINT point;
point.x = xCur;
point.y = yCur;
ClientToScreen(hwndParent, &point);
ScreenToClient(hwndTV, &point);
ImageList_DragMove(point.x, point.y);

// 暫時關閉不畫拖曳物件,讓Tree-View可以重畫它的內容.
ImageList_DragShowNoLock(FALSE);

// 取得滑鼠指標底下的Item,並將它設定成DropTarget Item.
TVHITTESTINFO tvht;
tvht.pt.x = point.x;
tvht.pt.y = point.y;

HTREEITEM htiTarget = TreeView_HitTest(hwndTV, &tvht);
if (NULL != htiTarget)
TreeView_SelectDropTarget(hwndTV, htiTarget);

// 繼續繪製拖曳的物件.
ImageList_DragShowNoLock(TRUE);
}
拖曳結束

Tree-View的父視窗接收到一個WM_LBUTTONUP訊息時,表示拖曳程序終止。應用程式執行相關狀態回覆並且根據自己的定義執行拖放動作的操作。
void Main_OnLButtonUp(HWND hwndTV)
{
if (!g_fDragging)
return;

// 取得拖放目標.
HTREEITEM htiDest = TreeView_GetDropHilight(hwndTV);
if (NULL != htiDest)
{
// To do: 執行實際的移動或相關操作.
}

// 釋放掉暫時的ImageList物件.
ImageList_EndDrag();

// 狀態回覆.
TreeView_SelectDropTarget(hwndTV, NULL, TRUE);
ReleaseCapture();
g_fDragging = FALSE;
}


參考連結

2009年6月17日 星期三

good spec

程式語言

  • 程式語言:C/C++
編輯器

  • 系統平台:Windows
  • 視窗框架:WTL
執行時期

  • 系統平台:Windows,MacOS/iPhone
  • 程式庫:smallworld2,stge
  • 第三方程式庫:Lua/SDL/zlib/Boost.Spirit

繪圖(gx)

  • GDI
  • SDL
  • OpenGL

編輯器使用WTL作視窗框架實作,所以主要是以C++ Template實作。而Runtime部份則整個使用C++ Template實作,主要區分成三大模組:good、ed和rt。另外還有個gx模組,簡單定義了圖形介面讓其它模組使用來作圖形繪製。

good模組提供了資源管理的功能,ed模組繼承good模組再擴充編輯功能,而rt模組繼承good模組實作Runtime及提供Script擴充介面。其實正確來說,rt模組並非繼承good模組,而是包含good模組,透過包含及使用good模組作為資源管理。

good模組是個狀態管理器,只能載入資源和讀取內容。ed模組則繼承good模組提供編輯資源內容的功能,可以修改資源並存檔。而rt模組透過good模組載入資源,再經由RunTime及Script將資源和物件關聯起來,並付予物件動作邏輯,最後再透過gx模組將結果呈現在畫面上。

2009年6月10日 星期三

good整合stge粒子系統

初步完成stge和good的整合。


stge本來是專門設計來編輯彈幕射擊遊戲的,但因為它本身是個粒子系統,所以並不侷限於只能應用在彈幕射擊遊戲。整合進good後,就能以stge製作粒子特效,再以good來製作圖形及邏輯,讓good可以作出更豐富的應用。

在使用上變成會需要使用到二種Script,一個是以Lua來編輯Gameplay,另外再使用stge語言來編輯粒子。編輯器對應新增的粒子資源作了對應的修改,讓使用者能新增Particle資源,如下圖所示。同時Script也需要增加幾條對應的API。


目前還只是初步整合,還有許多地方需要作細部調整和加強。

整合stge後,有個較麻煩的問題。因為stge使用Boost.Spirit來實作Parser,所以編譯時間大大的增加了不少,這對Debug的影響很大,要想辨法解決。

2009年6月9日 星期二

全銀幕(fullscreen)的iPhone應用程式

使用Xcode新建一個iPhone的專案,編譯好執行起來的應用程式預設情況下在畫面的最上方會有個狀態列,顯示電信業者、時間和電量等資訊。

要把這個狀態列隠藏起來讓應用程式變成full-screen很簡單,不需要修改到原來的程式碼,只需要修改一下設定即可。

打開Resources/Info.plist檔案,在上面按右鍵,點選Add Row新增一個新欄位,輸入名稱UIStatusBarHidden。接著在這個新欄位上點右鍵,在Value Type子選單中選擇Boolean將這個欄位的屬性改變為Boolean,然後勾選設成True。

完成後存檔,重編程式,再執行後就可以看到應用程式以full-screen方式執行。

2009年6月3日 星期三

Windows Mobile透過ActiveSync上網

這個方法可以讓Windows Mobile手機透過USB和電腦連接經由ActiveSync連線上網。

步驟如下:

  1. 在PC開啟Regedit。(開始->執行->Regedit)
  2. 點選進入HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows CE Services。
  3. 在"Windows CE Services"點選右鍵選新增DWORD值,名稱為"AllowLSP",值為"0"。
重新連接USB,完成。

現在可以在手機上經由USB透過PC開啟IE上網。
Related Posts Plugin for WordPress, Blogger...