Двойной клик по edit

Тема в разделе "WASM.BEGINNERS", создана пользователем zxcc, 4 фев 2010.

  1. zxcc

    zxcc New Member

    Публикаций:
    0
    Регистрация:
    21 окт 2006
    Сообщения:
    172
    Здравствуйте.Как можно отследить двойной клик мыши на edit контроле?
     
  2. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    The WM_LBUTTONDBLCLK message is posted when the user double-clicks the left mouse button while the cursor is in the client area of a window.
     
  3. zxcc

    zxcc New Member

    Публикаций:
    0
    Регистрация:
    21 окт 2006
    Сообщения:
    172
    Есть диалоговое окно на нём edit контрол.Не получается получить двойной клик по edit.
     
  4. Blackbeam

    Blackbeam New Member

    Публикаций:
    0
    Регистрация:
    28 дек 2008
    Сообщения:
    960
    Код (Text):
    1. Урок 20
    2.  
    3.  Сабклассинг окна
    4.  
    5.  
    6. Если вы уже некоторое время программируете в Windows, вы уже могли столкнуться с ситуацией, когда окно имеет почти все атрибуты, которые вам нужны, но не все. Сталкивались ли вы с ситуацией, когда вам требуется специальный вид edit control'а, который бы отфильтровывал ненужный текст? Первое, что может придти в голову, это написать свое собственное окно. Hо это действительно тяжелая работа, требующая значительного времени. Выходом является сабклассинг окна.
    7. Вкратце, сабклассинг окна позволяет получить контроль над сабклассированным окном. У вас будет абсолютный контроль над ним. Давайте рассмотрим пример, что прояснить данное утверждение. Предположите, что вам нужен text box, в котором можно вводить только шестнадцатиричные числа. Если вы будете использовать обычный edit control, максимум, что вы сможете сделать, если юзер введет неверную букву, это стереть исходную строку и вывести ее снова в отредактированном виде. По меньшей мере, это непрофессионально. Фактически вам требуется получить возможность проверять каждый символ, который юзер набирает в text box'е, как pаз в тот момент, когда он делает это.
    8. Теперь мы изучим как это сделать. Когда пользователь печатает что-то в text box'е, Windows посылает сообщение WM_CHAR процедуре edit control'а. Эта процедура окна находится внутри Windows, поэтому мы не можем модифицировать ее. Hо мы можем перенаправить поток сообщений к нашей оконной процедуре. Поэтому наша процедура окна первой получит возможность обработать сообщение, которое Windows пошлет edit control'у. Если наша qqпроцедура решит обработать сообщение, она так и сделает. Hо если она не захочет его обрабатывать, она может передать его оригинальной оконной процедуре. Таким образом, наша функция будет стоять между Windows и edit control'ом. Посмотрите на условную схему внизу.
    9.  
    10.        До сабклассинга
    11.  
    12.        Windows ==> процедура edit control'а
    13.  
    14.        После сабклассинга
    15.  
    16.        Windows ==> наша оконная процедура -----> процедура edit control'а
    17.  
    18.                Теперь мы можем рассмотреть то, каким образом происходит сабклассинг окна. Заметьте, что сабклассинг не ограничивается контролами, он может использоваться с любым окном. Давайте подумаем  о том, как Windows узнаёт, где находится процедура edit box'а. Hу?.. Поле lрfnWndрroc в структуре WNDCLASSEX. Если мы сможем поменять значение этого поля на адрес собственной структуры, Windows пошлет сообщение нашей процедуре окна вместо этого. Мы можем сделать это, вызвав SetWindowLong.
    19.  
    20.        SetWindowLong PROTO hWnd:DWORD, nIndex:DWORD, dwNewLong:DWORD
    21.  
    22.    hWnd = хэндл окна, чьи свойства мы хотим поменять.
    23.    nIndex = значение, которое нужно изменить.
    24.        GWL_EXSTYLE Установка нового расширенного стиля окна.
    25.        GWL_STYLE Установка нового стиля окна.
    26.        GWL_WNDPROC Установка нового адреса для процедры окна.
    27.        GWL_HINSTANCE Установка нового хэндла приложения.
    28.        GWL_ID Установка нового идентификатора окна.
    29.        GWL_USERDATA Установка 32-битного значения, ассоциирующегося с окном.
    30.        У каждого окна есть ассоциированное с ним 32-битное значение,
    31.        предназначенное для использования приложением в своих целях.
    32.  
    33.    dwNewLong = новое значение.
    34.  
    35.    Таким образом, наша работа проста: мы создаем процедуру окна, которая будет обрабатывать сообщения для edit control'а и затем вызывать SetWindowLong с флагом GWL_WNDPROC, которому передается адрес нашего окна в качестве третьего параметра. В случае, если вызов функции прошел нормально, возвращаемым значением является прежнее значение замещаемого параметра, в нашем случае - это адрес оригинальной процедуры окна. Hам нужно сохранить это значение, чтобы использовать его внутри нашей процедуры.
    36.  
    37.    Помните, что есть сообщения, которые нам не нужно будет обрабатывать. Их мы будем передавать оригинальной процедуре. Мы можем сделать это с помощью вызова функции CallWindowproc.
    38.  
    39.        CallWindowproc pROTO lpprevWndFunc:DWORD, \
    40.                                                    hWnd:DWORD,\
    41.                                                    Msg:DWORD,\
    42.                                                    wparam:DWORD,\
    43.                                                    lparam:DWORD
    44.  
    45.    lрrevWndFunc = адрес оригинальной процедуры окна. Остальные четыре значения - это те, что передаются нашей процедуре окна. Мы передаем их CallWindowproc.
    46.  
    47.    Пpимеp:
    48.    .386
    49.    .model flat,stdcall
    50.    option casemap:none
    51.    include \masm32\include\windows.inc
    52.    include \masm32\include\user32.inc
    53.    include \masm32\include\kernel32.inc
    54.    include \masm32\include\comctl32.inc
    55.    includelib \masm32\lib\comctl32.lib
    56.    includelib \masm32\lib\user32.lib
    57.    includelib \masm32\lib\kernel32.lib
    58.    WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
    59.    EditWndproc PROTO :DWORD,:DWORD,:DWORD,:DWORD
    60.    .data
    61.    ClassName  db "SubclassWinClass",0
    62.    AppName    db "Subclassing Demo",0
    63.    EditClass  db "EDIT",0
    64.    Message  db "You pressed Enter in the text box!",0
    65.    data?
    66.    hInstance  HINSTANCE ?
    67.    hwndEdit dd ?
    68.    OldWndProc dd ?
    69.    .code
    70.    start:
    71.        invoke GetModuleHandle, NULL
    72.        mov    hInstance,eax
    73.        invoke WinMain, hInstance,NULL,NULL, SW_SHOWDEFAULT
    74.        invoke Exitprocess,eax
    75.    WinMain proc
    76.    hInst:HINSTANCE,hprevInst:HINSTANCE,CmdLine:LpSTR,CmdShow:DWORD
    77.        LOCAL wc:WNDCLASSEX
    78.        LOCAL msg:MSG
    79.        LOCAL hwnd:HWND
    80.        mov   wc.cbSize,SIZEOF WNDCLASSEX
    81.        mov   wc.style, CS_HREDRAW or CS_VREDRAW
    82.        mov   wc.lpfnWndproc, OFFSET Wndproc
    83.        mov   wc.cbClsExtra,NULL
    84.        mov   wc.cbWndExtra,NULL
    85.        push  hInst
    86.        pop   wc.hInstance
    87.        mov   wc.hbrBackground,COLOR_AppWORKSpACE
    88.        mov   wc.lpszMenuName,NULL
    89.        mov   wc.lpszClassName,OFFSET ClassName
    90.        invoke LoadIcon,NULL,IDI_AppLICATION
    91.        mov   wc.hIcon,eax
    92.        mov   wc.hIconSm,eax
    93.        invoke LoadCursor,NULL,IDC_ARROW
    94.        mov   wc.hCursor,eax
    95.        invoke RegisterClassEx, addr wc
    96.  
    97. invoke CreateWindowEx,
    98. WS_EX_CLIENTEDGE,
    99. ADDR ClassName,
    100. ADDR AppName,
    101. WS_OVERLAPPED+WS_CAPTION+WS_SYSMENU+WS_MINIMIZEBOX\
    102. +WS_MAXIMIZEBOX+WS_VISIBLE,
    103. CW_USEDEFAULT, CW_USEDEFAULT,350,200,
    104. NULL,NULL, hInst,NULL
    105.  
    106.        mov   hwnd,eax
    107.  
    108.                                              .while TRUE
    109.  
    110.  invoke GetMessage, ADDR msg,NULL,0,0
    111.  
    112.                                             .BREAK .IF (!eax)
    113.  
    114.  invoke TranslateMessage, ADDR msg
    115.  invoke DispatchMessage, ADDR msg
    116.        .endw
    117.  mov eax,msg.wparam
    118.        ret
    119.  WinMain endp
    120.  Wndproc proc hWnd:HWND, uMsg:UINT, wparam:WpARAM, lparam:LpARAM
    121.  
    122.                                             .if uMsg==WM_CREATE
    123.  
    124.  invoke CreateWindowEx,
    125. WS_EX_CLIENTEDGE,
    126. ADDR EditClass,
    127. NULL,
    128. WS_CHILD+WS_VISIBLE+WS_BORDER,
    129. 20,20,300,25,
    130. hWnd,NULL, hInstance,NULL
    131.  
    132. mov hwndEdit,eax
    133. invoke SetFocus,eax
    134.            
    135.            ; Subclass it!
    136.            
    137. invoke SetWindowLong,hwndEdit,GWL_WNDPROC,addr EditWndProc
    138. mov OldWndProc,eax
    139.                                          .elseif uMsg==WM_DESTROY
    140. invoke PostQuitMessage,NULL
    141.        .else
    142.  invoke DefWindowProc,hWnd,uMsg,wparam,lparam
    143.     ret
    144.        .endif
    145.  xor eax,eax
    146.    ret
    147.  WndProc endp
    148.  EditWndproc PROC hEdit:DWORD,uMsg:DWORD,wparam:DWORD,lparam:DWORD
    149.  
    150.                                           .if uMsg==WM_CHAR
    151. mov eax,wparam
    152. .if (al>="0" && al<="9") || (al>="A" && al<="F") || (al>="a" && al<="f") ||
    153. al==VK_BACK
    154.                                          .if al>="a" && al<="f"
    155. sub al,20h
    156.                .endif
    157. invoke CallWindowProc,OldWndProc,hEdit,uMsg,eax,lparam
    158.     ret
    159.            .endif
    160.        .elseif uMsg==WM_KEYDOWN
    161.            mov eax,wparam
    162.            .if al==VK_RETURN
    163.                invoke MessageBox,hEdit,addr Message,addr
    164.    AppName,MB_OK+MB_ICONINFORMATION
    165.                invoke SetFocus,hEdit
    166.            .else
    167.                invoke CallWindowproc,OldWndproc,hEdit,uMsg,wparam,lparam
    168.                ret
    169.            .endif
    170.        .else
    171.            invoke CallWindowproc,OldWndproc,hEdit,uMsg,wparam,lparam
    172.            ret
    173.        .endif
    174.        xor eax,eax
    175.        ret
    176.    EditWndproc endp
    177.    end start
    178.  
    179.    Анализ:
    180.                invoke SetWindowLong,hwndEdit,GWL_WNDpROC,addr EditWndproc
    181.                mov OldWndproc,eax
    182.  
    183.    После того, как edit control создан, мы сабклассим его, вызывая SetWindowLong и замещая адрес оригинальной процедуры окна нашим собственным адресом. Заметьте, что мы сохраняем значение адреса оригинальной процедуры, чтобы впоследствии использовать его при вызове CallWindowproc.
    184.    Заметьте, что EditWndрroc - это обычная оконная процедура.
    185.  
    186.          .if uMsg==WM_CHAR
    187.                mov eax,wparam
    188.                .if (al>="0" && al<="9") || (al>="A" && al<="F") || (al>="a" && al<="f") || al==VK_BACK
    189.                    .if al>="a" && al<="f"
    190.                        sub al,20h
    191.                    .endif
    192.                    invoke CallWindowproc,OldWndproc,hEdit,uMsg,eax,lparam
    193.                    ret
    194.                .endif
    195.  
    196.    Внутри EditWndрroc, мы фильтруем сообщения WM_CHAR. Если введен символ в диапазоне 0-9 или a-f, мы передаем его оригинальной процедуре окна. Если это символ нижнего регистра, мы конвертируем его в верхний, добавляя  20h. Заметьте, что если символ не тот, который мы ожидали, мы пропускаем его. Мы не передаем его оригинальной процедуре окна. Поэтому, когда пользователь печатает  что-нибудь отличное от 0-9 или a-f, символ не появляется в edit control'е.
    197.  
    198.            .elseif uMsg==WM_KEYDOWN
    199.                mov eax,wparam
    200.                .if al==VK_RETURN
    201.                    invoke MessageBox,hEdit,addr Message,addr
    202.        AppName,MB_OK+MB_ICONINFORMATION
    203.                    invoke SetFocus,hEdit
    204.                .else
    205.                    invoke CallWindowproc,OldWndproc,hEdit,uMsg,wparam,lparam
    206.                    ret
    207.                .end
    208.  
    209.    Я хочу продемонстрировать силу сабклассинга через перехват клавиши Enter. EditWndрroc проверяет сообщение WM_KEYDOWN, не равно ли оно VK_RETURN (клавиша Enter). Если это так, она отображает окно с сообщением "You pressed the Enter key in the text box!". Если это не клавиша Enter, она передает сообщение оригинальной процедуре.
    210.    Вы можете использовать сабклассинг окна, чтобы получить контроль над другими окнами. Эту мощную технику вам следует иметь в своем арсенале.
    211. -----------------------
    212. [C] Iczelion, пер. Aquila.
     
  5. zxcc

    zxcc New Member

    Публикаций:
    0
    Регистрация:
    21 окт 2006
    Сообщения:
    172
    Спасибо.Попробую.