purebasic.info

PureBasic forum
Текущее время: Пн апр 22, 2019 7:26 am

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 10 ] 
Автор Сообщение
 Заголовок сообщения: WM_Сообщения
СообщениеДобавлено: Сб янв 19, 2019 2:49 am 
Не в сети
профессор

Зарегистрирован: Чт фев 09, 2017 10:37 am
Сообщений: 452
Благодарил (а): 33 раз.
Поблагодарили: 48 раз.
Пункты репутации: 0
Решил конвертировать свои примеры WM_Сообщений ради изучения как написать это на PureBasic, ну и ради того что я например не нахожу некоторых рабочих примеров поиском.

WM_HSCROLL
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
Declare MyWindowCallback(WindowId, Message, wParam, lParam)
 
Global k = 0, hSlider1, hSlider2
GUI = OpenWindow(0, 0, 0, 420, 285,"Горизонтальный", #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget)
hSlider1 = TrackBarGadget(1, 10, 5, 200, 30, 0, 185)
hSlider2 = TrackBarGadget(2, 10, 35, 200, 30, 0, 185)
TextGadget(3, 10, 140, 400, 125,   "WM_HSCROLL - сообщение позволяет получить величину регулятора в момент его использования, а не зацикливать проверку состояния" + #LF$ + "Если горизонтальных регуляторов более одного, то функция срабатывает при задействовании любого из горизонтальных регуляторов, а также при использовании полосы прокрутки.",0)
TextGadget(4, 10, 75, 400, 55,   "",0)
 
SetWindowCallback(@MyWindowCallback())
 
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
 
Procedure MyWindowCallback(WindowId, Message, wParam, lParam)
        Protected Result = #PB_ProcessPureBasicEvents, sMsg$, nScrollCode, value
 
        Select Message
                Case #WM_HSCROLL
;                       Это (LoWord и HiWord) должно быть в Protected процедуры а не под #WM_HSCROLL, если используется другие WM_Сообщения
                        nScrollCode = wParam & $FFF ; LoWord
                        value = wParam >> 16            ; HiWord
                        Select lParam
                                Case hSlider1
                                        sMsg$ = "Слайдер = 1" + #LF$ + "Значение = "
                                        Select nScrollCode
                                                Case #SB_THUMBTRACK
                                                        sMsg$ + value + #LF$ + "Метод = Удерживание левой кнопкой мыши"
                                                Case #SB_THUMBPOSITION
                                                        sMsg$ + value + #LF$ + "Метод = Колёсиком мыши"
                                                Case #SB_LINELEFT
                                                        value = GetGadgetState(1)
                                                        sMsg$ + value + #LF$ + "Метод = Стрелка влево/вверх"
                                                Case #SB_LINERIGHT
                                                        value = GetGadgetState(1)
                                                        sMsg$ + value + #LF$ + "Метод = Стрелка вправо/вниз"
                                                Case #SB_PAGELEFT
                                                        value = GetGadgetState(1)
                                                        sMsg$ + value + #LF$ + "Метод = Клик слева от ползунка"
                                                Case #SB_PAGERIGHT
                                                        value = GetGadgetState(1)
                                                        sMsg$ + value + #LF$ + "Метод = Клик справа от ползунка"
                                        EndSelect
                                        If nScrollCode <> 8
                                                SetGadgetText(4 , sMsg$)
                                        EndIf
                                        ;                           Прозрачность(0, 255 - GetGadgetState(1))
                                Case hSlider2
                                        If nScrollCode = #SB_THUMBTRACK
                                                SetGadgetText(4 , "2 - " + value)
                                        EndIf
                                Case 0
                                        If nScrollCode = #SB_THUMBTRACK
                                                SetGadgetText(4 , "3 - " + value)
                                        EndIf
                        EndSelect
 
                        k + 1
                        SetWindowTitle(0 , "Вызов " + k + " раз, c=" + nScrollCode + ", v=" + value)
        EndSelect
        ProcedureReturn Result
EndProcedure



Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: WM_Сообщения
СообщениеДобавлено: Сб янв 19, 2019 4:18 am 
Не в сети
профессор

Зарегистрирован: Чт фев 09, 2017 10:37 am
Сообщений: 452
Благодарил (а): 33 раз.
Поблагодарили: 48 раз.
Пункты репутации: 0
WM_NCHITTEST
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
Declare MyWindowCallback(WindowId, Message, wParam, lParam)
 
Global Dim Assot.s(21)
; задаём значения, ассоциируя число с текстом подсказки
Assot(1) = "1 - Клиентская область"
Assot(2) = "2 - Заголовок"
Assot(3) = "3 - Иконка"
Assot(5) = "5 - Меню"
Assot(6) = "6 - Горизонтальная прокрутка"
Assot(7) = "7 - Вертикальная прокрутка"
Assot(8) = "8 - Свернуть"
Assot(9) = "9 - Развернуть"
Assot(10) = "10 - Левый грань"
Assot(11) = "11 - Правая грань"
Assot(12) = "12 - Верхняя грань"
Assot(13) = "13 - Левый верхний угол"
Assot(14) = "14 - Правый верхний угол"
Assot(15) = "15 - Нижняя грань"
Assot(16) = "16 - Левый нижний угол"
Assot(17) = "17 - Правый нижний угол"
Assot(18) = "18 - Рамка" ; если стиль без возможности изменения размера окна (-1)
Assot(20) = "20 - Закрыть"
Assot(21) = "21 - Знак вопроса"
 
Global k = 0
OpenWindow(0, 0, 0, 780, 100,"WM_NCHITTEST", #WS_EX_TOPMOST | #WS_HSCROLL | #WS_VSCROLL | #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget)
 
SetWindowColor(0, $bddada)
If CreateMenu(0, WindowID(0))  ; Здесь начинается создание меню....
        MenuTitle("Файл")
        MenuItem(1, "Открыть")
EndIf
 
SetWindowCallback(@MyWindowCallback())
 
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
 
Procedure MyWindowCallback(WindowId, Message, wParam, lParam)
        Protected Result = #PB_ProcessPureBasicEvents, info_ID.s, iProc, X, Y
       
        Select Message
                Case #WM_NCHITTEST
                        iProc = DefWindowProc_(WindowId, Message, wParam, lParam)
                        k + 1
                        ; Координаты мыши
                        X = lParam & $FFF ; LoWord
                        Y = lParam >> 16  ; HiWord
                       
                        ; Возвращаемый массив iProc содержит 5 значений, первое из которых код указывающий над каким элементом окна находится мышь остальные повторяют параметры hWnd, Msg, wParam, lParam
                        info_ID = "?"
                        For i = 0 To 18
                                If iProc = i ;  iProc(0)
                                        info_ID = Assot(i)
                                        Break
                                EndIf
                        Next
                        ; ToolTip(info_ID) ; просмотр возвращаемых параметров (перенаправил в заголовок)
                        SetWindowTitle(0 , "Вызов " + k + " раз, x=" + X + ", y=" + Y + " код=" + info_ID)
                        ; Если мышь в клиентской области то возвращаем окну, что мышь на заголовке (это позволяет перемещать окно за клиентскую область)
                        If iProc = #HTCLIENT ;  iProc(0)
                                ProcedureReturn #HTCAPTION
                        EndIf
;                       If iProc = #HTCLOSE
;                               End ; Выход при наведении на кнопку закрытия
;                       EndIf
;                       If iProc = #HTCLIENT
;                               ProcedureReturn HTBOTTOMRIGHT ; а здесь возвращаем окну, что мышь готова изменить размер
;                       EndIf
        EndSelect
        ProcedureReturn Result
EndProcedure
 



Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: WM_Сообщения
СообщениеДобавлено: Ср янв 23, 2019 1:28 am 
Не в сети
профессор

Зарегистрирован: Чт фев 09, 2017 10:37 am
Сообщений: 452
Благодарил (а): 33 раз.
Поблагодарили: 48 раз.
Пункты репутации: 0
WM_NOTIFY

К сожалению часть кода не осилил, там где закомментировано, потому что надо искать аналоги функций, но и я не понял как создать собственную структуру со строкой заданной ширины (пример в код-архиве работает но другой), а во втором случае "структура структуры" - имя полученное из структуры использовать для имени второй структуры. Также посмотрел примеры в код-архиве, которых оказалось предостаточно, и почти все выдавали ошибку при запуске и кроме того они не нацелены чтобы показать чисто движок WM_NOTIFY, то есть реакцию на что либо, а в куче с чем-то и без вывода инфы о событиях. Ну и на форуме тоже полно примеров.

Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
Declare MyWindowCallback(hWin, Msg, wParam, lParam)
 
help.s = "Пример показывает возможность назначить управление/действия" + #CRLF$ + "пунктам используя клавиши модификаторы и способ клика мыши" + #CRLF$ + #CRLF$ + "Для каждого ListView можно назначить своё поведение," + #CRLF$ + "которое определяется в выборе -Case hWndListView-"
Global k = 0
Global hListView
 
GUI = OpenWindow(0, 0, 0, 550, 320,"Кликайте по элементам в ListView, нажмите F2", #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget)
 
hListView = ListIconGadget(0,  2, 2, 199, 88, "кол1  ", 60, #LVS_EDITLABELS | #PB_ListIcon_CheckBoxes | #PB_ListIcon_FullRowSelect)
AddGadgetColumn(0, 1, "кол2", 60)
AddGadgetColumn(0, 2, "кол3  ", 60)
 
AddGadgetItem(0, -1, "пункт 1" + #LF$ + "1111" + #LF$ + "1 в кол 3")
AddGadgetItem(0, -1, "пункт 2" + #LF$ + "2222" + #LF$ + "2 в кол 3")
AddGadgetItem(0, -1, "пункт 3" + #LF$ + "3333" + #LF$ + "3 в кол 3")
 
hEdit = EditorGadget(1, 2, 95, 545, 222, #ES_AUTOVSCROLL | #WS_VSCROLL | #ES_NOHIDESEL | #ES_WANTRETURN)
SetGadgetText(1, help)
GetGadgetColor(1 , $fffbd7)
 
btn1 = ButtonGadget(2, 225, 66, 70, 25, "Первая")
btn2 = ButtonGadget(3, 315, 66, 70, 25, "Вторая")
 
SetWindowCallback(@MyWindowCallback())
 
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
 
Procedure MyWindowCallback(hWin, Msg, wParam, lParam)
        Protected Result = #PB_ProcessPureBasicEvents
        *pnmhdr.NMHDR =lParam
        *pitema.NMITEMACTIVATE =lParam
        *pnmlv.NMLISTVIEW =lParam
 
; *pnmhdr\hWndFrom
; *pnmhdr\IDFrom
; *pnmhdr\code
        Select Msg
                Case #WM_NOTIFY
    k + 1
        SetWindowTitle(0 , "Вызов " + k + " ID =" + wParam)
                        Select *pnmhdr\hWndFrom
                                Case hListView
                                        Select *pnmhdr\code
                                                Case #LVN_COLUMNCLICK
                                                        SetGadgetText(1, "LVN_COLUMNCLICK" + #TAB$ + "клик на заголовке колонки" + #CRLF$ + "дескриптор:" + #TAB$ + *pnmhdr\hWndFrom + #CRLF$ + "идентификатор:" + #TAB$ + *pnmhdr\IDFrom + #TAB$ + "(порядковый номер элемента в окне)" + #CRLF$ + "№ колонки:" + #TAB$ + *pnmlv\iSubItem + #TAB$ + "(отсчёт от 0)")
 
                                                Case #NM_DBLCLK ; левый двойной клик мышкой по пункту
                                                       
                                                        SetGadgetText(1, "NM_DBLCLK" + #TAB$ + "ДВОЙНОЙ клик левой кнопкой мыши" + #CRLF$ + "дескриптор:" + #TAB$ + *pnmhdr\hWndFrom + #CRLF$ + "идентификатор:" + #TAB$ + *pnmhdr\IDFrom + #TAB$ + "(порядковый номер элемента в GUI)" + #CRLF$ + "код клика:" + #TAB$ + *pnmhdr\code + #TAB$ + "(определяет правой или левой, двойной или одинарный клик мыши)" + #CRLF$ + "№ пункта:" + #TAB$ + *pnmlv\iItem + #TAB$ + "(номер строки, отсчёт от 0, -1 пустое пространство)" + #CRLF$ + "№ колонки:" + #TAB$ + *pnmlv\iSubItem + #TAB$ + "(отсчёт от 0)" + #CRLF$ + "удерж. клавиша:" + #TAB$ + *pitema\uKeyFlags + #TAB$ + "(0=ничего; 1=Alt, 2=Ctrl, 4=Shift, 3,5,6,7 - комбинации)")
 
                                                Case #NM_CLICK ; левый клик мышкой по пункту
                                                        SetGadgetText(1, "NM_CLICK" + #TAB$ + "одинарный клик левой кнопкой мыши" + #CRLF$ + "дескриптор:" + #TAB$ + *pnmhdr\hWndFrom + #CRLF$ + "идентификатор:" + #TAB$ + *pnmhdr\IDFrom + #TAB$ + "(порядковый номер элемента в GUI)" + #CRLF$ + "код клика:" + #TAB$ + *pnmhdr\code + #TAB$ + "(определяет правой или левой, двойной или одинарный клик мыши)" + #CRLF$ + "№ пункта:" + #TAB$ + *pnmlv\iItem + #TAB$ + "(номер строки, отсчёт от 0, -1 пустое пространство)" + #CRLF$ + "№ колонки:" + #TAB$ + *pnmlv\iSubItem + #TAB$ + "(отсчёт от 0)" + #CRLF$ + "удерж. клавиша:" + #TAB$ + *pitema\uKeyFlags + #TAB$ + "(0=ничего; 1=Alt, 2=Ctrl, 4=Shift, 3,5,6,7 - комбинации)")
 
                                                ; Case #LVN_KEYDOWN ; нажатие любой клавиши
                                                        ; *pnmlv.NMLVKEYDOWN
                                                        ; *pnmlv=lParam
                                                       
                                                        ; If Int(Right(GetGadgetText(1), 2)) <> *pnmlv\VKey
                                                                ; SetGadgetText(1, #CRLF$ + "Нажата клавиша №: " + *pnmlv\VKey, 1)
                                                        ; EndIf
                                                        ; Select *pnmlv\VKey
                                                                ; Case 113; F2
                                                                        ; Tmp = GetGadgetState(0)
                                                                        ; If Tmp >= 0
                                                                                ; _GUICtrlListView_EditLabel(hListView, Tmp) ; SendMessage_(hWnd, #LVM_EDITLABEL, iIndex, 0, 0, "wparam", "lparam", "hwnd")
                                                                                ; SetGadgetText(1, "Нажата клавиша F2" + #CRLF$ +"Редактирование пункта " + Tmp)
                                                                                ; ProcedureReturn False
                                                                        ; Else
                                                                                ; SetGadgetText(1, "Нужно выделить пункт")
                                                                        ; EndIf
                                                        ; EndSelect
 
                                                ; Case #LVN_ENDLABELEDITA, #LVN_ENDLABELEDITW ; конец редактирования пункта
                                                        ; *pnmlv.NMLVDISPINFO
                                                        ; *pnmlv=lParam
                                                        ; Protected tBuffer = DllStructCreate("char Text[" + *pnmlv\TextMax + "]", *pnmlv\Text)
                                                        ; If Len(*tBuffer\Text))
                                                                ; ProcedureReturn True
                                                        ; EndIf
 
                                                Case #NM_RCLICK ; правый клик мышкой по пункту
                                                        SetGadgetText(1, "NM_RCLICK" + #TAB$ + "одинарный клик ПРАВОЙ кнопкой мыши" + #CRLF$ + "дескриптор:" + #TAB$ + *pnmhdr\hWndFrom + #CRLF$ + "идентификатор:" + #TAB$ + *pnmhdr\IDFrom + #TAB$ + "(порядковый номер элемента в GUI)" + #CRLF$ + "код клика:" + #TAB$ + *pnmhdr\code + #TAB$ + "(определяет правой или левой, двойной или одинарный клик мыши)" + #CRLF$ + "№ пункта:" + #TAB$ + *pnmlv\iItem + #TAB$ + "(номер строки, отсчёт от 0, -1 пустое пространство)" + #CRLF$ + "№ колонки:" + #TAB$ + *pnmlv\iSubItem + #TAB$ + "(отсчёт от 0)" + #CRLF$ + "удерж. клавиша:" + #TAB$ + *pitema\uKeyFlags + #TAB$ + "(0=ничего; 1=Alt, 2=Ctrl, 4=Shift, 3,5,6,7 - комбинации)")
 
                                                Case #NM_RDBLCLK ; правый двойной клик мышкой по пункту
                                                        SetGadgetText(1, "NM_RDBLCLK" + #TAB$ + "ДВОЙНОЙ клик ПРАВОЙ кнопкой мыши" + #CRLF$ + "дескриптор:" + #TAB$ + *pnmhdr\hWndFrom + #CRLF$ + "идентификатор:" + #TAB$ + *pnmhdr\IDFrom + #TAB$ + "(порядковый номер элемента в GUI)" + #CRLF$ + "код клика:" + #TAB$ + *pnmhdr\code + #TAB$ + "(определяет правой или левой, двойной или одинарный клик мыши)" + #CRLF$ + "№ пункта:" + #TAB$ + *pnmlv\iItem + #TAB$ + "(номер строки, отсчёт от 0, -1 пустое пространство)" + #CRLF$ + "№ колонки:" + #TAB$ + *pnmlv\iSubItem + #TAB$ + "(отсчёт от 0)" + #CRLF$ + "удерж. клавиша:" + #TAB$ + *pitema\uKeyFlags + #TAB$ + "(0=ничего; 1=Alt, 2=Ctrl, 4=Shift, 3,5,6,7 - комбинации)")
                                        EndSelect
                                ; Case Else
                                        ; Обработка события кнопок
                                        ; Protected #BCN_HOTITEMCHANGE = -1249
                                        ; *pnmlv2.NMBHOTITEM
                                        ; *pnmlv2=lParam
                                        ; Protected , _
                                                ; hCtrl_1 = *pnmhdr\hWndFrom
                                                ; hCtrl = *pnmlv2\hCtrl_1
                                                ; sText = ""
 
                                        ; Select *pnmlv2\Code
                                                ; Case #BCN_HOTITEMCHANGE ; Win XP и выше
                                                        ; If (*pnmlv2\dwFlags & 0x10) = 0x10
                                                                ; sText = "наведена"
                                                        ; ElseIf (*pnmlv2\dwFlags & 0x20) = 0x20
                                                                ; sText = "оставлена"
                                                        ; EndIf
                                                        ; SetGadgetText(1, "Кнопка " + GetGadgetText(hCtrl) + " " + sText + #CRLF$ + "идентификатор" + #Tab$ + *pnmlv2\IDFrom + #CRLF$ + "дескриптор:" + #Tab$ + hWndFrom)
                                        ; EndSelect
                        EndSelect
    EndSelect
 
        ProcedureReturn Result
EndProcedure
 



Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: WM_Сообщения
СообщениеДобавлено: Ср янв 23, 2019 11:32 am 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11432
Благодарил (а): 4 раз.
Поблагодарили: 459 раз.
AZJIO писал(а):
Код:
1
2
3
4
; Protected tBuffer = DllStructCreate("char Text[" + *pnmlv\TextMax + "]", *pnmlv\Text)
; If Len(*tBuffer\Text))
    ; ProcedureReturn True
; EndIf[

Код:
1
2
3
4
5
If *pnmlv\Text
  If Len(PeekS(*pnmlv\Text))
    ProcedureReturn #True
  EndIf
EndIf

Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
hwnd = OpenWindow(0,0,0,320,300, "",#PB_Window_SystemMenu|#PB_Window_ScreenCentered) 
lv=ListIconGadget(0, 60,50,200,200, "1234", 180, #PB_ListIcon_GridLines | #PB_ListIcon_FullRowSelect | #LVS_EDITLABELS)
For i=1 To 10
  AddGadgetItem(0, -1, "Строка "+i)
Next
 
Repeat
  EventID=WaitWindowEvent()
  Select EventID
    Case #WM_LBUTTONDBLCLK
      lvi.lvhittestinfo
      GetCursorPos_(@lvi\pt)
      GetWindowRect_(lv,@lvpos.rect)
      lvi\pt\x-lvpos\left
      lvi\pt\y-lvpos\top
      SendMessage_(lv, #LVM_HITTEST, 0, @lvi)
      edititem = lvi\iitem
      editcontrol = SendMessage_(lv,#LVM_EDITLABEL,edititem,0)
    Case #WM_KEYUP
      If editcontrol
        If EventwParam()<>#VK_RETURN
          editstring.s=Space(255)
          PokeW(@editstring, 255)
          SendMessage_(editcontrol,#EM_GETLINE,0,@editstring)
        Else
          If editstring<>""
            editcontrol = 0
            line.LV_ITEM
            line\Mask     = #LVIF_TEXT
            line\pszText  = @editstring
            SendMessage_(lv, #LVM_SETITEMTEXT, edititem, @line)
            editstring=""
          EndIf
        EndIf
      EndIf
  EndSelect
Until EventID=#PB_Event_CloseWindow


_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: WM_Сообщения
СообщениеДобавлено: Вт фев 26, 2019 6:51 am 
Не в сети
профессор

Зарегистрирован: Чт фев 09, 2017 10:37 am
Сообщений: 452
Благодарил (а): 33 раз.
Поблагодарили: 48 раз.
Пункты репутации: 0
Доделал пример в том виде, в котором он был у меня ранее. То есть работает переименование по F2 и кликом и реакция на наведение мыши на кнопку. Добавил 3 события.

WM_NOTIFY
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
EnableExplicit
Declare MyWindowCallback(hWin, Msg, wParam, lParam)
#BCN_HOTITEMCHANGE = -1249
 
Structure NMBHOTITEM
        hWndFrom.l
        IDFrom.i
        Code.i
        dwFlags.l
EndStructure
 
Structure NMLVSCROLL Extends NMHDR
        DX.i
        DY.i
EndStructure
 
Structure NMLVKEYDOWN Extends NMHDR Align 1
        VKey.w
        Flags.l
EndStructure
 
Global hListView, help.s, k = 0, hEdit, btn1, btn2
help.s = "Пример показывает возможность назначить управление/действия" + #CRLF$ + "пунктам используя клавиши модификаторы и способ клика мыши" + #CRLF$ + #CRLF$ + "Для каждого ListView можно назначить своё поведение," + #CRLF$ + "которое определяется в выборе -Case hWndListView-"
 
 
OpenWindow(0, 0, 0, 550, 320,"Кликайте по элементам в ListView, нажмите F2", #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget)
 
hListView = ListIconGadget(0,  2, 2, 199, 88, "кол1  ", 60, #LVS_EDITLABELS | #PB_ListIcon_CheckBoxes | #PB_ListIcon_FullRowSelect)
AddGadgetColumn(0, 1, "кол2", 60)
AddGadgetColumn(0, 2, "кол3  ", 60)
 
AddGadgetItem(0, -1, "пункт 1" + #LF$ + "1111" + #LF$ + "1 в кол 3")
AddGadgetItem(0, -1, "пункт 2" + #LF$ + "2222" + #LF$ + "2 в кол 3")
AddGadgetItem(0, -1, "пункт 3" + #LF$ + "3333" + #LF$ + "3 в кол 3")
AddGadgetItem(0, -1, "пункт 4" + #LF$ + "4444" + #LF$ + "4 в кол 3")
 
hEdit = EditorGadget(1, 2, 95, 545, 222, #ES_AUTOVSCROLL | #WS_VSCROLL | #ES_NOHIDESEL | #ES_WANTRETURN)
SetGadgetText(1, help)
GetGadgetColor(1 , $fffbd7)
 
btn1 = ButtonGadget(2, 225, 66, 70, 25, "Первая")
btn2 = ButtonGadget(3, 315, 66, 70, 25, "Вторая")
 
SetWindowCallback(@MyWindowCallback())
 
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
 
Procedure MyWindowCallback(hWin, Msg, wParam, lParam)
        Protected item, Text$, tmp$
        Static tmpOld$
        Protected Result = #PB_ProcessPureBasicEvents
        Protected *pnmhdr.NMHDR =lParam
        Protected *pitema.NMITEMACTIVATE =lParam
        Protected *pnmlv.NMLISTVIEW =lParam
        Protected *vlkey.NMLVKEYDOWN
        Protected *Info.NMLVDISPINFO
        Protected *pnmlv2.NMBHOTITEM
        Protected *scroll.NMLVSCROLL
       
        Select Msg
                Case #WM_NOTIFY
                        k + 1
                        SetWindowTitle(0 , "Вызов " + k + " ID =" + wParam)
                        Select *pnmhdr\hWndFrom
                                Case hListView
                                        Select *pnmhdr\code
                                                Case #LVN_COLUMNCLICK
                                                        SetGadgetText(1, "LVN_COLUMNCLICK" + #TAB$ + "клик на заголовке колонки" + #CRLF$ + "дескриптор:" + #TAB$ + *pnmhdr\hWndFrom + #CRLF$ + "идентификатор:" + #TAB$ + *pnmhdr\IDFrom + #TAB$ + "(порядковый номер элемента в окне)" + #CRLF$ + "№ колонки:" + #TAB$ + *pnmlv\iSubItem + #TAB$ + "(отсчёт от 0)")
                                                       
                                                Case #NM_DBLCLK ; левый двойной клик мышкой по пункту
                                                       
                                                        SetGadgetText(1, "NM_DBLCLK" + #TAB$ + "ДВОЙНОЙ клик левой кнопкой мыши" + #CRLF$ + "дескриптор:" + #TAB$ + *pnmhdr\hWndFrom + #CRLF$ + "идентификатор:" + #TAB$ + *pnmhdr\IDFrom + #TAB$ + "(порядковый номер элемента в GUI)" + #CRLF$ + "код клика:" + #TAB$ + *pnmhdr\code + #TAB$ + "(определяет правой или левой, двойной или одинарный клик мыши)" + #CRLF$ + "№ пункта:" + #TAB$ + *pnmlv\iItem + #TAB$ + "(номер строки, отсчёт от 0, -1 пустое пространство)" + #CRLF$ + "№ колонки:" + #TAB$ + *pnmlv\iSubItem + #TAB$ + "(отсчёт от 0)" + #CRLF$ + "удерж. клавиша:" + #TAB$ + *pitema\uKeyFlags + #TAB$ + "(0=ничего; 1=Alt, 2=Ctrl, 4=Shift, 3,5,6,7 - комбинации)")
                                                       
                                                Case #NM_CLICK ; левый клик мышкой по пункту
                                                        SetGadgetText(1, "NM_CLICK" + #TAB$ + "одинарный клик левой кнопкой мыши" + #CRLF$ + "дескриптор:" + #TAB$ + *pnmhdr\hWndFrom + #CRLF$ + "идентификатор:" + #TAB$ + *pnmhdr\IDFrom + #TAB$ + "(порядковый номер элемента в GUI)" + #CRLF$ + "код клика:" + #TAB$ + *pnmhdr\code + #TAB$ + "(определяет правой или левой, двойной или одинарный клик мыши)" + #CRLF$ + "№ пункта:" + #TAB$ + *pnmlv\iItem + #TAB$ + "(номер строки, отсчёт от 0, -1 пустое пространство)" + #CRLF$ + "№ колонки:" + #TAB$ + *pnmlv\iSubItem + #TAB$ + "(отсчёт от 0)" + #CRLF$ + "удерж. клавиша:" + #TAB$ + *pitema\uKeyFlags + #TAB$ + "(0=ничего; 1=Alt, 2=Ctrl, 4=Shift, 3,5,6,7 - комбинации)")
                                                        ProcedureReturn #True
                                                Case #NM_HOVER ; Высылается элементом list-view когда мышь поверх пункта
                                                        SetGadgetText(1, "NM_HOVER" + #TAB$ + "наведение курсора мыши" + #CRLF$ + "дескриптор:" + #TAB$ + *pnmhdr\hWndFrom + #CRLF$ + "идентификатор:" + #TAB$ + *pnmhdr\IDFrom + #TAB$ + "(порядковый номер элемента в GUI)" + #CRLF$ + "код клика:" + #TAB$ + *pnmhdr\code + #TAB$ + "(определяет правой или левой, двойной или одинарный клик мыши)" + #CRLF$ + "№ пункта:" + #TAB$ + *pnmlv\iItem + #TAB$ + "(номер строки, отсчёт от 0, -1 пустое пространство)" + #CRLF$ + "№ колонки:" + #TAB$ + *pnmlv\iSubItem + #TAB$ + "(отсчёт от 0)")
                                                Case #LVN_HOTTRACK ; Высылает в ListView, когда пользователь перемещает курсор мыши над пунктом
                                                        tmp$ = "LVN_HOTTRACK" + #TAB$ + "наведение курсора мыши" + #CRLF$ + "дескриптор:" + #TAB$ + *pnmhdr\hWndFrom + #CRLF$ + "идентификатор:" + #TAB$ + *pnmhdr\IDFrom + #TAB$ + "(порядковый номер элемента в GUI)" + #CRLF$ + "код клика:" + #TAB$ + *pnmhdr\code + #TAB$ + "(определяет правой или левой, двойной или одинарный клик мыши)" + #CRLF$ + "№ пункта:" + #TAB$ + *pnmlv\iItem + #TAB$ + "(номер строки, отсчёт от 0, -1 пустое пространство)" + #CRLF$ + "№ колонки:" + #TAB$ + *pnmlv\iSubItem + #TAB$ + "(отсчёт от 0)"
                                                        If tmp$<>tmpOld$
                                                                SetGadgetText(1, tmp$)
                                                                tmpOld$ = tmp$
                                                        EndIf
                                                Case #LVN_BEGINSCROLL ; Начинается операция прокрутки, минимальная ОС WinXP
                                                        *scroll.NMLVSCROLL=lParam
                                                        SetGadgetText(1, "LVN_BEGINSCROLL" + #TAB$ + "прокрутка" + #CRLF$ + "DX:" + #TAB$ + *scroll\DX + #CRLF$ + "DY:" + #TAB$ + *scroll\DY)
 
                                                Case #LVN_KEYDOWN ; нажатие любой клавиши
                                                        *vlkey.NMLVKEYDOWN=lParam
                                                        If Int(Val(Right(GetGadgetText(1), 2))) <> *vlkey\VKey
;                                                               SetGadgetText(1, #CRLF$ + "Нажата клавиша №: " + Str(*vlkey\VKey))
                                                                AddGadgetItem(1 , -1 , #CRLF$ + "Нажата клавиша №: " + Str(*vlkey\VKey))
                                                        EndIf
                                                        Select *vlkey\VKey
                                                                Case 113; F2
                                                                        item = GetGadgetState(0)
                                                                        If item >= 0
                                                                                ; edititem = GetItemLV()
                                                                                SendMessage_(hListView,#LVM_EDITLABEL,item,0) ; editcontrol =
                                                                                SetGadgetText(1, "Нажата клавиша F2" + #CRLF$ +"Редактирование пункта " + Str(item))
                                                                                ProcedureReturn #False
                                                                        Else
                                                                                SetGadgetText(1, "Нужно выделить пункт")
                                                                        EndIf
                                                        EndSelect
                                                       
                                                Case #LVN_ENDLABELEDITA, #LVN_ENDLABELEDITW ; конец редактирования пункта
                                                        *Info.NMLVDISPINFO=lParam
                                                        If *Info\item\mask & #LVIF_TEXT
                                                                If Len(PeekS(*Info\item\pszText))
                                                                        ProcedureReturn #True
                                                                EndIf
                                                        EndIf
                                                       
                                                Case #NM_RCLICK ; правый клик мышкой по пункту
                                                        SetGadgetText(1, "NM_RCLICK" + #TAB$ + "одинарный клик ПРАВОЙ кнопкой мыши" + #CRLF$ + "дескриптор:" + #TAB$ + *pnmhdr\hWndFrom + #CRLF$ + "идентификатор:" + #TAB$ + *pnmhdr\IDFrom + #TAB$ + "(порядковый номер элемента в GUI)" + #CRLF$ + "код клика:" + #TAB$ + *pnmhdr\code + #TAB$ + "(определяет правой или левой, двойной или одинарный клик мыши)" + #CRLF$ + "№ пункта:" + #TAB$ + *pnmlv\iItem + #TAB$ + "(номер строки, отсчёт от 0, -1 пустое пространство)" + #CRLF$ + "№ колонки:" + #TAB$ + *pnmlv\iSubItem + #TAB$ + "(отсчёт от 0)" + #CRLF$ + "удерж. клавиша:" + #TAB$ + *pitema\uKeyFlags + #TAB$ + "(0=ничего; 1=Alt, 2=Ctrl, 4=Shift, 3,5,6,7 - комбинации)")
                                                       
                                                Case #NM_RDBLCLK ; правый двойной клик мышкой по пункту
                                                        SetGadgetText(1, "NM_RDBLCLK" + #TAB$ + "ДВОЙНОЙ клик ПРАВОЙ кнопкой мыши" + #CRLF$ + "дескриптор:" + #TAB$ + *pnmhdr\hWndFrom + #CRLF$ + "идентификатор:" + #TAB$ + *pnmhdr\IDFrom + #TAB$ + "(порядковый номер элемента в GUI)" + #CRLF$ + "код клика:" + #TAB$ + *pnmhdr\code + #TAB$ + "(определяет правой или левой, двойной или одинарный клик мыши)" + #CRLF$ + "№ пункта:" + #TAB$ + *pnmlv\iItem + #TAB$ + "(номер строки, отсчёт от 0, -1 пустое пространство)" + #CRLF$ + "№ колонки:" + #TAB$ + *pnmlv\iSubItem + #TAB$ + "(отсчёт от 0)" + #CRLF$ + "удерж. клавиша:" + #TAB$ + *pitema\uKeyFlags + #TAB$ + "(0=ничего; 1=Alt, 2=Ctrl, 4=Shift, 3,5,6,7 - комбинации)")
                                        EndSelect
                                Default
                                        ; Обработка события кнопок
                                        *pnmlv2.NMBHOTITEM=lParam
                                        Text$ = ""
                                       
                                        Select *pnmlv2\Code
                                                Case #BCN_HOTITEMCHANGE ; Win XP и выше
                                                        If (*pnmlv2\dwFlags & $10) = $10
                                                                Text$ = "наведена"
                                                        ElseIf (*pnmlv2\dwFlags & $20) = $20
                                                                Text$ = "оставлена"
                                                        EndIf
                                                        SetGadgetText(1, "Кнопка " + GetGadgetText(*pnmhdr\IDFrom) + " " + Text$ + #CRLF$ + "идентификатор" + #TAB$ + Str(*pnmlv2\IDFrom) + #CRLF$ + "дескриптор:" + #TAB$ + Str(*pnmhdr\hWndFrom))
                                        EndSelect
                        EndSelect
        EndSelect
       
        ProcedureReturn Result
EndProcedure



Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: WM_Сообщения
СообщениеДобавлено: Пт мар 01, 2019 1:36 pm 
Не в сети
профессор

Зарегистрирован: Чт фев 09, 2017 10:37 am
Сообщений: 452
Благодарил (а): 33 раз.
Поблагодарили: 48 раз.
Пункты репутации: 0
Я скомпилировал код WM_NOTIFY в x64 и у меня пропала реакция на наведение на кнопку. Пытался менять тип переменных в структуре, но понял угадывать бесполезно, там ведь она должна соответствовать lParam, а не просто типу, то есть важна позиция в структуре.

И возник вопрос почему я создаю экземпляр структуры внутри процедуры? Во первых процедура вызывается настолько часто, при смещении мыши на 1 пиксел, допустим 100 раз в секунду выделяется память под десяток структур заполняется и уничтожается. А не проще ли создать структуры глобальными, хотя наверно лучше статичную Static?


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: WM_Сообщения
СообщениеДобавлено: Пт мар 01, 2019 1:57 pm 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11432
Благодарил (а): 4 раз.
Поблагодарили: 459 раз.
https://docs.microsoft.com/en-us/window ... mbchotitem
Код:
1
2
3
Structure NMBHOTITEM Extends NMHDR
  dwFlags.l
EndStructure


AZJIO писал(а):
почему я создаю экземпляр структуры внутри процедуры?
Не экземпляр, а указатель.

AZJIO писал(а):
допустим 100 раз в секунду выделяется память под десяток структур заполняется и уничтожается.
Только под указатели. Для этого резервируется 4 или 8 байт в стеке под каждый указатель. Это не требует много ресурсов.

AZJIO писал(а):
А не проще ли создать структуры глобальными, хотя наверно лучше статичную Static?
Прирост производительности будет примерно 0.000000002%.
Кроме того возможны вложенные вызовы процедуры что приведет к искажению данных.

_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: WM_Сообщения
СообщениеДобавлено: Пт мар 01, 2019 6:26 pm 
Не в сети
профессор

Зарегистрирован: Чт фев 09, 2017 10:37 am
Сообщений: 452
Благодарил (а): 33 раз.
Поблагодарили: 48 раз.
Пункты репутации: 0
Пётр писал(а):
Не экземпляр, а указатель.

Но под данные на которые указывает указатель винда должна выделить память. То есть должна сработать AllocateStructure, и FreeStructure

Пётр писал(а):
Кроме того возможны вложенные вызовы процедуры что приведет к искажению данных.
Так как они объявляются уже в заголовке процедуры, то вложенные будут использовать их же. А если глобальными, то просто для другой процедуры создать свои экземпляры, опять же это наверно для другого потока имеет смысл, потому что в одном потоке нельзя использовать одновременно несколько процедур, и так как в процедуре происходит заполнение экземпляра структуры до использования, то вроде как не возникнет ситуации искажённых данных.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: WM_Сообщения
СообщениеДобавлено: Пт мар 01, 2019 9:43 pm 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11432
Благодарил (а): 4 раз.
Поблагодарили: 459 раз.
AZJIO писал(а):
Но под данные на которые указывает указатель винда должна выделить память.
Глобальные экземпляры структур это не изменят. Винда как выделяла память, так и будет выделять.

AZJIO писал(а):
Так как они объявляются уже в заголовке процедуры, то вложенные будут использовать их же.
Они локальные и при каждом вызове процедуры создаются новые экземпляры. Тестовый код.
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Global Count=0
 
Procedure Test()
  Protected *pnmhdr.NMHDR
 
  If Count>=10
    ProcedureReturn
  EndIf
 
  Count+1
 
  *pnmhdr = AllocateStructure(NMHDR)
  Debug "Count "+Count+"  Point "+*pnmhdr+"  Allocate"
  Test()
  If *pnmhdr
    Debug "Count "+Count+"  Point "+*pnmhdr+"  Free"
    FreeStructure(*pnmhdr)
    *pnmhdr=0
  EndIf
EndProcedure
 
Test()

Состояние стека при выполнении условия
Код:
1
2
3
  If Count>=10
    ProcedureReturn
  EndIf

Изображение
Отладочный вывод при выполнении кода.
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Count 1  Point 59377620  Allocate
Count 2  Point 59377644  Allocate
Count 3  Point 59377668  Allocate
Count 4  Point 59377692  Allocate
Count 5  Point 59377716  Allocate
Count 6  Point 59377740  Allocate
Count 7  Point 59377764  Allocate
Count 8  Point 59377788  Allocate
Count 9  Point 59377812  Allocate
Count 10  Point 59377836  Allocate
Count 10  Point 59377836  Free
Count 10  Point 59377812  Free
Count 10  Point 59377788  Free
Count 10  Point 59377764  Free
Count 10  Point 59377740  Free
Count 10  Point 59377716  Free
Count 10  Point 59377692  Free
Count 10  Point 59377668  Free
Count 10  Point 59377644  Free
Count 10  Point 59377620  Free

При замене Protected на Static указатель перестает быть локальным и становится статическим.
Стек.
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[ESP+0  ]  4198661       
[ESP+4  ]  6            
[ESP+8  ]  10            
[ESP+12 ]  4198873      
[ESP+16 ]  9            
[ESP+20 ]  4198873      
[ESP+24 ]  8            
[ESP+28 ]  4198873      
[ESP+32 ]  7            
[ESP+36 ]  4198873      
[ESP+40 ]  6            
[ESP+44 ]  4198873      
[ESP+48 ]  5            
[ESP+52 ]  4198873      
[ESP+56 ]  4            
[ESP+60 ]  4198873      
[ESP+64 ]  3            
[ESP+68 ]  4198873      
[ESP+72 ]  2            
[ESP+76 ]  4198873      
[ESP+80 ]  1            
[ESP+84 ]  4198873      
[ESP+88 ]  2130567168    
[ESP+92 ]  4198533      
[ESP+96 ]  31656160  

Отладочный вывод.
Код:
1
2
3
4
5
6
7
8
9
10
11
Count 1  Point 5113812  Allocate
Count 2  Point 5113836  Allocate
Count 3  Point 5113860  Allocate
Count 4  Point 5113884  Allocate
Count 5  Point 5113908  Allocate
Count 6  Point 5113932  Allocate
Count 7  Point 5113956  Allocate
Count 8  Point 5113980  Allocate
Count 9  Point 5114004  Allocate
Count 10  Point 5114028  Allocate
Count 10  Point 5114028  Free

Только один Free потому что указать один. Но память выделяется несколько раз, т. е. происходит утечка памяти.


Вложения:
Debug.png [35.68 KiB]
Скачиваний: 0

_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)
Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: WM_Сообщения
СообщениеДобавлено: Вс апр 14, 2019 12:28 pm 
Не в сети
профессор

Зарегистрирован: Чт фев 09, 2017 10:37 am
Сообщений: 452
Благодарил (а): 33 раз.
Поблагодарили: 48 раз.
Пункты репутации: 0
Перевожу winapi_library и наткнулся на пример, где Debug выводил результат GetProp_(...). И он прям досил отладку и тут я понимаю, что это обычный калбэк и как то надо отфильтровать сообщение. Сделал вывод
Код:
1
Debug Str(GetProp_(wParam, "PB_ID")) + "   " + Str(uMsg)

то есть определил с каким сообщением приходит наведение на кнопку, оказалось 32 ($20), ввёл условие WM_SETCURSOR и "If Cur_ID <> old_ID" и пример уже выводит только смену ID

WM_SETCURSOR
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
EnableExplicit
 
Procedure WinCallback(hWnd, uMsg, wParam, lParam)
        Protected Cur_ID
        Static old_ID = 0
        Select uMsg
                Case #WM_SETCURSOR
                        Cur_ID = GetProp_(wParam, "PB_ID")
                        If Cur_ID <> old_ID
                                old_ID = Cur_ID
                                SetWindowTitle(0 , "PB_ID = " + Str(Cur_ID)) ; Пишем в заголовок окна
;                               SetGadgetText(1, "PB_ID = " +  Str(Cur_ID))
;                               Debug Str(Cur_ID)
                        EndIf
        EndSelect
        ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
 
If OpenWindow(0,0,0,500,250,"Пример",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
        TextGadget(1,10,10,50,20,"Текст:",#SS_NOTIFY)
        ButtonGadget(2,100,10,100,20,"Кнопка",0)
       
        SetWindowCallback(@WinCallback())
       
        Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf



Вернуться наверх
 Профиль  
 
Показать сообщения за:  Сортировать по:  
Начать новую тему Ответить на тему  [ Сообщений: 10 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group (блог о phpBB)
Сборка создана CMSart Studio
Русская поддержка phpBB