找回密码
 加入
搜索
查看: 4963|回复: 6

[效率算法] 请懂WM_NOTIFY()的解释一下,在6楼![已解决]

[复制链接]
发表于 2012-11-13 21:17:51 | 显示全部楼层 |阅读模式
本帖最后由 blue_dvd 于 2012-11-25 21:24 编辑

看下面代码
#include <GuiListView.au3>
#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>

Const $width = 280, $height = 320
$Form1 = GUICreate("Test", $width, $height, (@DesktopWidth - $width) / 2, (@DesktopHeight - $height) / 2)
$Listview = GUICtrlCreateListView('Column 1|Column 2|Column 3', 7, 60, 266, 161, BitOR($LVS_SINGLESEL, $LVS_REPORT))
$hListView = GUICtrlGetHandle($Listview)
_GUICtrlListView_SetExtendedListViewStyle($hListview, BitOR($LVS_EX_GRIDLINES, $LVS_EX_BORDERSELECT, $LVS_EX_FULLROWSELECT))
For $col = 0 To 2
        ; Set Text-Centered format for all three columns
        _GUICtrlListView_JustifyColumn($hListview, $col, 2)
Next
For $row = 0 To 9
        _GUICtrlListView_AddItem($hListview, $row)        ; 1st column
   _GUICtrlListView_AddSubItem($hListview, $row, 'x_' & $row, 1)        ; 2nd column
    _GUICtrlListView_AddSubItem($hListview, $row, 'y_' & $row, 2)        ; 3rd column
Next

GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY')
GUISetState(@SW_SHOW)

; Loop until user exits
Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

; http://msdn.microsoft.com/en-us/library/windows/desktop/bb775583(v=vs.85).aspx
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
        #forceref $hWnd, $iMsg, $iwParam
        Local $tNMHDR, $hWndFrom, $iCode

        $hWndListView = $hListView
        If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView)

        $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)  ; $tagNMHDR - Contains information about a notification message
        $hWndFrom = DllStructGetData($tNMHDR, 'hWndFrom')
        $iCode = DllStructGetData($tNMHDR, 'Code')

        Switch $hWndFrom
                Case $hWndListView
                        Switch $iCode
  Case $NM_CLICK ; Sent by a list-view control when user clicks an item with left mouse button
      $aHit = _GUICtrlListView_SubItemHitTest($hListView)
             MsgBox(0, "", "Item " & $aHit[0] & " is selected") ; Item index is zero based
                        EndSwitch
        EndSwitch
EndFunc
帮忙解释下
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
        #forceref $hWnd, $iMsg, $iwParam
        Local $tNMHDR, $hWndFrom, $iCode

        $hWndListView = $hListView
        If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView)

        $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)  ; $tagNMHDR - Contains information about a notification message
        $hWndFrom = DllStructGetData($tNMHDR, 'hWndFrom')
        $iCode = DllStructGetData($tNMHDR, 'Code')

        Switch $hWndFrom
                Case $hWndListView
                        Switch $iCode
  Case $NM_CLICK 
      $aHit = _GUICtrlListView_SubItemHitTest($hListView)
             MsgBox(0, "", "Item " & $aHit[0] & " is selected") ; Item index is zero based
                        EndSwitch
        EndSwitch
EndFunc
$aHit 
都没有声明怎么就可以赋值呢?
Switch $hWndFrom
                Case $hWndListView
                        Switch $iCode
  Case $NM_CLICK 
      $aHit = _GUICtrlListView_SubItemHitTest($hListView)
这些变量时什么意思?恳请写过的老师解释下!万分感谢!
 楼主| 发表于 2012-11-13 21:23:27 | 显示全部楼层
还有一个也是
Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
        Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR

        $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
        $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
        $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
        $iCode = DllStructGetData($tNMHDR, "Code")
        Switch $hWndFrom
                Case $hListView
                        Switch $iCode
                                Case $NM_CUSTOMDRAW
        If Not _GUICtrlListView_GetViewDetails($hWndFrom) Then Return $GUI_RUNDEFMSG
                                        Local $tCustDraw = DllStructCreate('hwnd hwndFrom;int idFrom;int code;dword DrawStage;hwnd hdc;long rect[4];dword ItemSpec;int ItemState;dword Itemlparam;dword clrText;dword clrTextBk;int SubItem; dword ItemType;dword clrFace;int IconEffect;int IconPhase;int PartID;int StateID;long rectText[4];int Align', $lParam)
          Local $iDrawStage, $iItem, $iSubitem, $hDC, $iColor1, $iColor2, $iColor3
                      $iDrawStage = DllStructGetData($tCustDraw, 'DrawStage')
                                        If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW 
                                        If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW
                                        If Not BitAND($iDrawStage, $CDDS_SUBITEM) Then Return $CDRF_DODEFAULT
                    $iItem = DllStructGetData($tCustDraw, 'ItemSpec')
                              $iSubitem = DllStructGetData($tCustDraw, 'SubItem')
                                        Select
                           Case _GUICtrlListView_GetItemChecked($hListView, $iItem)
                                       $iColor = RGB2BGR(0x7FFF00)
                                 DllStructSetData($tCustDraw, 'clrTextBk', $iColor)
                   Case Not (_GUICtrlListView_GetItemChecked($hListView, $iItem))
                                         $iColor = RGB2BGR(0xFFFFFF)
                                                        DllStructSetData($tCustDraw, 'clrTextBk', $iColor)
                                        EndSelect
                                        Return $CDRF_NEWFONT
                        EndSwitch
        EndSwitch
        Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func RGB2BGR($iColor)
        Return BitAND(BitShift(String(Binary($iColor)), 8), 0xFFFFFF)
EndFunc   ;==>RGB2BGR
其中
  Switch $hWndFrom
                Case $hListView
                        Switch $iCode
                                Case $NM_CUSTOMDRAW
这些变量和前一个例子差不多,搞不清这些变量表示何意,希望各位给个解释或链接!谢谢啦!
 楼主| 发表于 2012-11-13 21:26:18 | 显示全部楼层
再来个例子
#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <WindowsConstants.au3>
#include <GUIListView.au3>
#include <Array.au3>
  
$Form1 = GUICreate("Form1", 800, 600)
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
 
 
Local $iExWindowStyle = BitOR($WS_EX_DLGMODALFRAME, $WS_EX_CLIENTEDGE,$LVS_EX_CHECKBOXES,$LVS_EX_SIMPLESELECT)
Local $iExListViewStyle = BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_SUBITEMIMAGES, $LVS_EX_GRIDLINES,  $LVS_EX_DOUBLEBUFFER,$LVS_EX_CHECKBOXES,$LVS_EX_SIMPLESELECT)
 
  
$ListView1 = GUICtrlCreateListView("A      |B     |", 8, 8, 300, 200, -1, $iExWindowStyle)
GUISetState(@SW_SHOW)
For $I = 1 To 10
        GUICtrlCreateListViewItem($I, $ListView1)
Next
 
$hListView = GUICtrlGetHandle($Listview1)
  
 _GUICtrlListView_SetExtendedListViewStyle($ListView1, $iExListViewStyle)
 
 Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
 
 
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
        #forceref $hWnd, $iMsg, $iwParam
        Local $tNMHDR, $hWndFrom, $iCode
 
        $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)  
; $tagNMHDR - Contains information about a notification message
        $hWndFrom = DllStructGetData($tNMHDR, 'hWndFrom')
        $iCode = DllStructGetData($tNMHDR, 'Code')
 
        Switch $hWndFrom
                Case GuiCtrlGetHandle($ListView1)
                        Switch $iCode
   Case $NM_CLICK 
        Local $aHit = _GUICtrlListView_HitTest($hListView)
                  If $aHit[5] Then _GUICtrlListView_ClickItem($hListView, $aHit[0])
                                        If $aHit[0] <> -1 Then
                         $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)  
                               Local $Index = DllStructGetData($tInfo, "Index")
                                                _GUICtrlListView_SetItemChecked($hListView, -1, False)
                                                _GUICtrlListView_SetItemChecked($hListView, $Index)
                                        Else
                                                _GUICtrlListView_SetItemChecked($hListView, -1, False)
                                        EndIf
                                                                        
                        EndSwitch
        EndSwitch
EndFunc
其中
 Switch $hWndFrom
                Case GuiCtrlGetHandle($ListView1)
                        Switch $iCode
   Case $NM_CLICK 
        Local $aHit = _GUICtrlListView_HitTest($hListView)
                  If $aHit[5] Then _GUICtrlListView_ClickItem($hListView, $aHit[0])
还是很像,
$aHit 
直接就用了!也不明白怎么来的?
发表于 2012-11-13 21:34:41 | 显示全部楼层

标题

回复 3# blue_dvd


    楼主有钻研精神啊,三天都看了些啥呢??论坛有不少帖子讲windows消息的哦,可以搜搜看
发表于 2012-11-13 22:03:31 | 显示全部楼层
本帖最后由 netegg 于 2012-11-13 22:06 编辑

楼主看了三天都看什么了,哪个变量没声明?另外,注册消息,建议楼主去msdn看看系统是如何定义消息的
发表于 2012-11-13 22:43:13 | 显示全部楼层
本帖最后由 edisonx 于 2012-11-14 00:31 编辑

這是個說來話長的故事,首先樓主先確定,有先到 code 裡的連結看過說明 
http://msdn.microsoft.com/en-us/library/windows/desktop/bb775583(v=vs.85).aspx

接下來是很長的故事了...

---------------------------------------

長話短說,所有的子控,訊息都是以 SendMessage ( 另一個是 PostMessage) 做通訊,
裡面有四個參數,hWnd, iMsg, wParam, iParam。
hWnd 是通知視窗(窗口),iMsg 是訊息種類 (這大多的訊息都已被定義),wParam, lParam 是額外夾帶的參數。隨著控件之複雜度、需求不同,wParam, lParam 所夾帶的參數也不同。

wParam / lParam 舉幾個例子
WM_LBUTTONUP時,wParam 代表按下之虛擬鍵碼 (virtual keys);LOWORD(lParam) = 兇案發生之 x 座標 , HIWORD(lParam) = 兇案發生之 y 座標。
WM_CHAR時,wParam 代表 key code,lParam 代表 extended-key flag 。
上面兩個例子唯說明, wParam , lParam 會跟著 iMsg 不同,夾帶的訊息也不同,所以要查 MSDN。

第一種子控制的通知,即視窗訊息之子集合,大多看到 WM_XXXX 屬之,主要來自 WM_PARENTNOTIFY、WM_CTLCOLOR、WM_DRAWITEM、WM_MEASUREITEM、WM_DELETEITEM、WM_CHARTOITEM、WM_COMPAREITEM、WM_VSCROLL、WM_HSCROLL .... etc,因為怕文太過冗長,這裡我就不細講了。

第二種子控制之通知,與命令訊息共享,最常見到的便是 WM_COMMAND,儲如主選單 (菜單,menu)、Accelerator 均屬之。r所以在 上的按鍵訊息,一律由 WM_COMMAND 響應,再由 LOWORD(wParam) 判斷是由哪個子控發出之訊息。(當然這裡的敘述省略了很多情況與說明)


至於第三種子控制通之,就是 WM_NOTIFY,子控制通知其母視窗 (父窗口,parent window),然後 lParam 放的是一個結構體 (struct) - NMHRD,附上 MSDN 對這個結構體之註解
typedef struct tagNMHDR {
  HWND     hwndFrom; // A window handle to the control sending the message. 
  UINT_PTR idFrom;   // An identifier of the control sending the message. 看哪個子控制發出的訊息
  UINT     code;     // A notification code. This member can be one of the common notification codes (see Notifications under General Control Reference), or it can be a control-specific notification code. 其他子控制額外的 msg (notification codes)
} NMHDR;
這個 struct 前兩個參數可以輕易得知,那第三個參數呢?notification code ? 怎辦?
還是一樣,MSDN 是 Windows coder 的好朋友。 Event notification code

補註 : 上面的 Event notifcation code link 給錯了,對問題沒幫助,樓主要的是 List-View notifcation ,全都是 LVM_XXXX 及 NM_XXXX ,其它常見子控制的 notifcation 在 MSDN 上之 Control Library (Windows) 都有詳細記載與說明。拿這例之 list-view 而言,進去 link 後,選 List View ,左半邊再選 List View Control Reference,就會發現有個 List-View Notifications 連結在和你招手了。其他子控之 Notification 也是一樣的方式做查詢 < 用到再查就好,背 Win32 API Reference 可能比背劍橋字典還難 >

為什麼要搞這麼複雜?原因很簡單,因某些子控制訊息要夾帶的參數沒那麼簡單了,所以直接包個 sturct 過去。

補註:這段說的可能沒那麼清楚,這樣想會清楚一點。

第一類子控訊息如 WM_VHSCROLL、WM_VSCROLL 之參數可以由 lParam、wParam 調閱查知;
第二類子控訊息只有一種:WM_COMMAND,由於這類子控較為簡易,故 lParam、wParam 夠用;
第三類子控訊息 WM_NOTIFY,而 WM_NOTIFY 裡面又有細分子控之訊息 (含發出這個訊息的子控制識別 ID、哪個視窗所發出、發出之 NOTIFY 訊息種類),如上面 List-View 裡的 EM_CLICK 便是 WM_NOTIFY 裡之一種額外訊息,但 SendMessage 裡面已經沒有另一個 iMsg 可以傳了,所以只好把這些訊息再包成 struct,放在 lParam 裡,傳遞出去。

--------------------------------------


OK,囉哩八嗦的故事,愛迪生十世 沒細看您的 code ( 主要是認為給魚吃不如給釣芉) ,長話短說說完了,剩下的擅用 MSDN 及 網路資源 應可了解程式碼在寫些什麼東西了,其它的就不再多說。

---------------------------------------

[ 註 ] 由於擔心所用之名詞不被理解,故盡可能附上原文。



评分

参与人数 3威望 +2 金钱 +40 贡献 +5 收起 理由
afan + 2 + 5 +
seeyou + 30 赞!内容详实,标记学习。
annybaby + 10 学习了~~

查看全部评分

 楼主| 发表于 2012-11-25 21:23:43 | 显示全部楼层
回复 6# edisonx
感谢edisonx 的教程,慢慢学习做好笔记!
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-11-18 09:38 , Processed in 0.092041 second(s), 27 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表