就像Windows程式裡拖動一樣的效果。
分析一下,滑鼠拖動實際上就是在一個表單上按下滑鼠,改變滑鼠的cursor表徵圖再按下不放,移動滑鼠,在任何一個表單鬆開滑鼠按鍵。
主要是二個動作的處理:一個是按下滑鼠,一個是鬆開的,都會在相應的表單中產生事件。
要解決的一個問題是當我們按鈕滑鼠時,改變了滑鼠的cursor表徵圖,拖動滑鼠到一個表單,鬆開了按鍵,也許這個表單並不是我們的目標表單,這時我們需要把滑鼠的cursor表徵圖改回原來的,而我們又不可能在所有的表單中都去寫一個處理滑鼠的cursor表徵圖過程。所以我們在一個地方來處理滑鼠鬆開時改變cursor表徵圖過程。
ucGUI裡的所有滑鼠事件都會經過WMTouch.c裡的WM_HandlePID過程來處理,這樣需要在這個過程裡截獲對應的事件,實際就是WM_PID_STATE_CHANGED事件,而我們要在一個對應的地方調用恢複滑鼠的cursor表徵圖問題,我想WM_HBKWIN表單是一個很好的地方,這樣我們在WM_HandlePID裡產生WM_PID_STATE_CHANGED事件處理時,把所有的事件也轉寄給WM_HBKWIN表單.
我們新增一個自己的訊息:
#define WM_PID_STATE_CHANGED_ALL 45
加如下的代碼:
if(CHWin.hWin != WM_HBKWIN)
{
WM_PID_STATE_CHANGED_INFO Info2;
Info2.x = Info.x;
Info2.y = Info.y;
Info2.State = Info.State;
Info2.StatePrev = Info.StatePrev;
WM_MESSAGE Msg2;
Msg2.Data.p = &Info2;
Msg2.hWinSrc = Msg.hWinSrc;
Msg2.MsgId = WM_PID_STATE_CHANGED_ALL;
WM_SendMessage(WM_HBKWIN,&Msg2);
}
這樣我們所有的表單的滑鼠事件都會發給WM_HBKWIN表單,我們在WM_HBKWIN表單的回調裡再處理:
case WM_PID_STATE_CHANGED_ALL: //所有表單發生WM_PID_STATE_CHANGED這個事件,都會發到這裡
{
WM_PID_STATE_CHANGED_INFO * cinfo = (WM_PID_STATE_CHANGED_INFO *)(pMsg->Data.p);
//按鈕的任何一次單擊鬆開
if(cinfo->State == 0){
DropDevSelectID = -1;
GUI_CURSOR_Select(&GUI_CursorArrowS);//改回預設的表徵圖
}
break;
}
DropDevSelectID是一個我用來記錄資訊的一個變數,當在源表單上按下滑鼠拖動時,我就用DropDevSelectID記錄下當時選擇的對像.如下:
//按鈕拖動
if(NCode == WM_NOTIFICATION_CLICKED){
if(Id == GUI_ID_LISTBOX0){
DropDevSelectID = getSelectpDevID(); //設定當前選擇的ID
if(DropDevSelectID == -1)
break;
GUI_CURSOR_Select(&GUI_CursorCrossL); //改變滑鼠的一個表徵圖。
}
}
上面的 DropDevSelectID = getSelectpDevID()就是記錄一下當前選擇的一個對像ID,這樣我們在上面的鬆開滑鼠處理過程裡就知道選擇的是什麼了。
好了,我們還要在目的表單中處理滑鼠鬆開事件:
case WM_PID_STATE_CHANGED:
//如果這個變數記錄了一個對像,就認為是從另一個表單來的拖動
if(DropDevSelectID != -1)
{
。。。;//處理
}
這樣就實現了一個窗對拖動的DockDrop功能,當然像這樣,有多次個DockDrop功能我們這樣就得處理多少個類似DropDevSelectID的變數,實際上在一個應用裡,
我們的滑鼠在一個時間點只有一個拖動的動作,這樣我們可以定義一個通用的對像來處理,具體的就自己怎麼做了!
對於滑鼠的表徵圖可以自己定義一個GUI_CURSOR對像,指定自己的表徵圖。
以前的代碼實現,現在搞上來.