Окно с изменяемым размером без бордюра

Тема в разделе "WASM.WIN32", создана пользователем elimli, 25 май 2007.

  1. elimli

    elimli New Member

    Публикаций:
    0
    Регистрация:
    13 янв 2007
    Сообщения:
    20
    Я сделал окошка в котором изменеие размера производится с помощью некого элемента окна который на на left mouse down шлет WM_NCLBUTTONDOWN к HTTOPLEFT, т.е. после нажатия на этот элемент начинается изменеие размера окна
    Код (Text):
    1. void OnLBDown(...)
    2. {
    3.     PostMessage(WM_NCLBUTTONDOWN, HTTOPLEFT, NULL);
    4. }
    Все работает просто замечательно, но я не могу избавится от бордюра окна. Окно создается через CreateWindow с параметром (WS_THICKFRAME или WS_DLGFRAME) и окружено тонким бордюром. Если создать окно без WS_THICKFRAME бордюр исчезает, но окно перестает быть resizable и не меняет своего размера на PostMessage(WM_NCLBUTTONDOWN, HTTOPLEFT, NULL);
    Как бы сесть на елку не уколов попу?
     
  2. kush

    kush New Member

    Публикаций:
    0
    Регистрация:
    24 май 2007
    Сообщения:
    46
    а если до начала изменения размеров установить WS_THICKFRAME, а после изменения его убрать ?
     
  3. elimli

    elimli New Member

    Публикаций:
    0
    Регистрация:
    13 янв 2007
    Сообщения:
    20
    Хммм, в принципе можно, только не совсем понятно когда убирать WS_THICKFRAME. Еще немного раздражает этот бордюр который появляется во время изменения размера. Вот сделать бы его невидимым ...
     
  4. elimli

    elimli New Member

    Публикаций:
    0
    Регистрация:
    13 янв 2007
    Сообщения:
    20
    Еще вопрос: может как-то можно поменять цвет этого бордюра?
     
  5. kush

    kush New Member

    Публикаций:
    0
    Регистрация:
    24 май 2007
    Сообщения:
    46
    А через DC окна закрасить нельзя ?
     
  6. elimli

    elimli New Member

    Публикаций:
    0
    Регистрация:
    13 янв 2007
    Сообщения:
    20
    kush
    Я думал об этом. Пробовал сделать:
    SetBkColor(GetDC(), RGB(0xFF, 0, 0));
    Результат - нулевой
     
  7. kush

    kush New Member

    Публикаций:
    0
    Регистрация:
    24 май 2007
    Сообщения:
    46
    elimli

    Форум, конечно, asm - овский, но в Delphi можно это сделать без труда.
    1) Создаешь форму со стилем fsNone (ни бордюра, ни заголовка)
    2) Изменяешь размер: Form1.Width := newWidth;

    Скорее всего это можно сделать и в Borland C, а вот как на чистом WinAPI ?
    Может посмотришь в их сорцы и по ним поймешь ?
     
  8. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
  9. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
  10. elimli

    elimli New Member

    Публикаций:
    0
    Регистрация:
    13 янв 2007
    Сообщения:
    20
    AsmGuru62
    Я попробовал в оконной ф-ии просто отбрасывать (retrun 0) WM_NCHITTEST. Окно перстаэт реагировать на мышь, но бордюр на месте :dntknw:
     
  11. kero

    kero Модератор SOURCES & 2LZ Команда форума

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
    AsmGuru62

    >Надо просто отвечать на сообщение WM_NCHITTEST. Никаких стилей и всё работает на ура.

    Не уверен, что с WM_NCHITTEST получится проще, чем без WM_NCHITTEST:

    собственная разметка периметра окна наподобие HT(LEFT/TOP/RIGHT/BOTTOM),
    на WM_SETCURSOR - SetCursor(LoadCursor),
    на WM_LBUTTONDOWN - DefWindowProc(WM_SYSCOMMAND,SC_SIZE+),

    - и вот вам эмуляция WS_THICKFRAME, с положенными краевыми курсорами, но без бордюра.
     
  12. kero

    kero Модератор SOURCES & 2LZ Команда форума

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
    >эмуляция WS_THICKFRAME, с положенными краевыми курсорами, но без бордюра.

    Пример (сразу и для top-level, и для child):

    Код (Text):
    1. .data
    2. _main  db "SizeBoxToo",0
    3. _child db "Static",0
    4. .data?
    5. .code
    6.  
    7. QuasiHitTest proc hWnd:HWND
    8.     local pt:POINT
    9.     local rt:RECT
    10.     invoke GetCursorPos,addr pt
    11.     invoke GetWindowRect,hWnd,addr rt
    12.     xor eax,eax
    13.     mov ecx,pt.x
    14.     cmp ecx,rt.left
    15.     jl @ret
    16.     cmp ecx,rt.right
    17.     jg @ret
    18.     mov ecx,pt.y
    19.     cmp ecx,rt.top
    20.     jl @ret
    21.     cmp ecx,rt.bottom
    22.     jg @ret
    23.     mov eax,3
    24.     mov ecx,rt.right
    25.     sub ecx,4
    26.     cmp pt.x,ecx
    27.     jge @f
    28.     dec eax
    29.     mov ecx,rt.left
    30.     add ecx,4
    31.     cmp pt.x,ecx
    32.     jge @f
    33.     dec eax
    34. @@:
    35.     mov edx,3
    36.     mov ecx,rt.bottom
    37.     sub ecx,4
    38.     cmp pt.y,ecx
    39.     jge @f
    40.     dec edx
    41.     mov ecx,rt.top
    42.     add ecx,4
    43.     cmp pt.y,ecx
    44.     jge @f
    45.     dec edx
    46. @@:
    47.     shl edx,1
    48.     mov ecx,edx
    49.     shl edx,2
    50.     add edx,ecx ; 10*edx
    51.     add eax,edx
    52. @ret:
    53.     ret
    54. QuasiHitTest endp
    55.  
    56. WndProc proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
    57.  
    58.     mov eax,uMsg
    59.     .if eax==WM_DESTROY
    60.         invoke PostQuitMessage,0
    61.  
    62.     .elseif eax==WM_SETCURSOR
    63.         invoke QuasiHitTest,hWnd
    64.         .if eax==11 || eax==33
    65.             mov eax,32642             ; \
    66.         .elseif eax==31 || eax==13
    67.             mov eax,32643             ; /
    68.         .elseif eax==21 || eax==23
    69.             mov eax,32644             ; -
    70.         .elseif eax==12 || eax==32
    71.             mov eax,32645             ; |
    72. ;       .elseif eax==22
    73. ;           mov eax,32649
    74.         .else
    75.             mov eax,32512
    76.         .endif
    77.         invoke LoadCursor,0,eax
    78.         invoke SetCursor,eax
    79.  
    80.     .elseif eax==WM_LBUTTONDOWN
    81.         invoke QuasiHitTest,hWnd   ; quasi:
    82.         .if     eax==21            ; HTLEFT
    83.             mov eax,SC_SIZE+1
    84.         .elseif eax==23            ; HTRIGHT
    85.             mov eax,SC_SIZE+2
    86.         .elseif eax==12            ; HTTOP
    87.             mov eax,SC_SIZE+3
    88.         .elseif eax==11            ; HTTOPLEFT
    89.             mov eax,SC_SIZE+4
    90.         .elseif eax==13            ; HTTOPRIGHT
    91.             mov eax,SC_SIZE+5
    92.         .elseif eax==32            ; HTBOTTOM
    93.             mov eax,SC_SIZE+6
    94.         .elseif eax==31            ; HTBOTTOMLEFT
    95.             mov eax,SC_SIZE+7
    96.         .elseif eax==33            ; HTBOTTOMRIGHT
    97.             mov eax,SC_SIZE+8
    98.         .elseif eax==22            ; HTCLIENT (HTCAPTION)
    99.             mov eax,SC_MOVE+1
    100.         .endif
    101.         jmp @f
    102.  
    103.     .elseif eax==WM_RBUTTONUP
    104.         mov eax,SC_CLOSE
    105. @@:
    106.         mov wParam,eax
    107.         mov uMsg,WM_SYSCOMMAND
    108.         jmp @f
    109.  
    110.     .else
    111. @@:
    112.         invoke GetWindowLong,hWnd,GWL_USERDATA
    113.         push lParam
    114.         push wParam
    115.         push uMsg
    116.         push hWnd
    117.         .if eax==0
    118.             call DefWindowProc
    119.         .else
    120.             push eax
    121.             call CallWindowProc
    122.         .endif
    123.         jmp @f
    124.     .endif
    125.     xor eax,eax
    126. @@:
    127.     ret
    128. WndProc endp
    129.  
    130. WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
    131.     local wc:WNDCLASSEX
    132.     local msg:MSG
    133.     local hWnd:HWND
    134.     mov wc.cbSize,sizeof WNDCLASSEX
    135.     mov wc.style,CS_DBLCLKS
    136.     mov wc.lpfnWndProc, offset WndProc
    137.     mov wc.cbClsExtra,0
    138.     mov wc.cbWndExtra,0
    139.     push hInst
    140.     pop wc.hInstance
    141.     mov wc.hbrBackground,COLOR_WINDOW+1
    142.     mov wc.lpszMenuName,0
    143.     mov wc.lpszClassName,offset _main
    144.     invoke LoadIcon,0,IDI_APPLICATION
    145.     mov wc.hIcon,eax
    146.     mov wc.hIconSm,eax
    147.     invoke LoadCursor,0,IDC_ARROW
    148.     mov wc.hCursor,eax
    149.     invoke RegisterClassEx,addr wc
    150.     invoke CreateWindowEx,WS_EX_TOPMOST,offset _main,offset _main,WS_POPUP OR WS_SYSMENU OR WS_CLIPCHILDREN OR WS_MINIMIZEBOX,100,100,400,200,0,0,hInst,0
    151.     mov hWnd,eax
    152.     invoke ShowWindow,hWnd,CmdShow
    153.     invoke UpdateWindow,hWnd
    154.     invoke CreateWindowEx,0,offset _child,offset _main,WS_CHILD OR WS_VISIBLE OR SS_NOTIFY,100,60,200,80,hWnd,0,hInst,0
    155.     mov hWnd,eax
    156.     invoke SetWindowLong,hWnd,GWL_WNDPROC,offset WndProc
    157.     invoke SetWindowLong,hWnd,GWL_USERDATA,eax
    158.     .while TRUE
    159.         invoke GetMessage,addr msg,0,0,0
    160.         .break .if (!eax)
    161.         invoke TranslateMessage,addr msg
    162.         invoke DispatchMessage,addr msg
    163.     .endw
    164.     mov eax,msg.wParam
    165.     ret
    166. WinMain endp
    167.  
    168. start:
    169.     invoke GetModuleHandle,0
    170.     invoke WinMain,eax,0,0,SW_SHOWDEFAULT
    171.     invoke ExitProcess,eax
    172. end start
     
  13. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    kero
    Ваш код отвечает на WM_SETCURSOR и WM_LBUTTONDOWN, а надо отвечать только на одно сообщение - WM_NCHITTEST. Windows самa установит требуемую функциональность. Все курсоры и прочее.
     
  14. kero

    kero Модератор SOURCES & 2LZ Команда форума

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
    AsmGuru62

    >Ваш код отвечает на WM_SETCURSOR и WM_LBUTTONDOWN, а надо отвечать только на одно сообщение - WM_NCHITTEST.
    >Windows самa установит требуемую функциональность. Все курсоры и прочее.

    Было бы интересно взглянуть на ваш код,
    особливо для случая сплошного HTCLIENT, как в моем примере.

    P.S. И почему так категорично - "надо" ? :)
     
  15. kero

    kero Модератор SOURCES & 2LZ Команда форума

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
    "О WM_NCHITTEST в последний раз" :)

    А вот и нет. Далеко не все равно, какое окно долбит WM_NCHITTEST.

    Код (Text):
    1. .const
    2. BorderWidth equ 4
    3. CornerLenght equ 20
    4. .data
    5. _class db "SizeBoxToo",0
    6. _sysmenu db "+ WS_SYSMENU",0
    7. _static db "Static",0
    8. _edit db "Edit",0
    9. .data?
    10. .code
    11.  
    12. HitTest1 proc po:DWORD,mi:DWORD,ma:DWORD
    13.   mov edx,po
    14.   xor eax,eax
    15.   mov ecx,mi
    16.   cmp edx,ecx
    17.   jl @f         ; 0
    18.   inc eax
    19.   add ecx,BorderWidth
    20.   cmp edx,ecx
    21.   jl @f         ; 1
    22.   inc eax
    23.   add ecx,CornerLenght-BorderWidth
    24.   cmp edx,ecx
    25.   jl @f         ; 2
    26.   inc eax
    27.   mov ecx,ma
    28.   sub ecx,CornerLenght
    29.   cmp edx,ecx
    30.   jl @f         ; 3
    31.   inc eax
    32.   add ecx,CornerLenght-BorderWidth
    33.   cmp edx,ecx
    34.   jl @f         ; 4
    35.   inc eax
    36.   add ecx,BorderWidth
    37.   cmp edx,ecx
    38.   jl @f         ; 5
    39.   xor eax,eax   ; 0
    40. @@:
    41.   ret
    42. HitTest1 endp
    43.  
    44. HitTest2 proc hWnd:HWND
    45.   local pt:POINT
    46.   local rt:RECT
    47.   invoke GetCursorPos,addr pt
    48.   invoke GetWindowRect,hWnd,addr rt
    49.   invoke HitTest1,pt.y,rt.top,rt.bottom
    50.   push eax
    51.   invoke HitTest1,pt.x,rt.left,rt.right
    52.   shl eax,4
    53.   pop ecx
    54.   add eax,ecx
    55.   ret
    56. HitTest2 endp
    57.  
    58.  
    59. WndProc proc uses ebx hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
    60.   local buf[128]:BYTE
    61.  
    62.   .if uMsg==WM_DESTROY
    63.     invoke PostQuitMessage,0
    64.  
    65.   .elseif uMsg==WM_NCHITTEST
    66. ;    invoke DefWindowProc,hWnd,uMsg,wParam,lParam
    67. ;    mov ebx,eax
    68.     invoke HitTest2,hWnd
    69.     .if     eax==13h
    70.       mov eax,HTLEFT
    71.     .elseif eax==53h
    72.       mov eax,HTRIGHT
    73.     .elseif eax==31h
    74.       mov eax,HTTOP
    75.     .elseif eax==11h || eax==21h || eax==12h
    76.       mov eax,HTTOPLEFT
    77.     .elseif eax==51h || eax==41h || eax==52h
    78.       mov eax,HTTOPRIGHT
    79.     .elseif eax==35h
    80.       mov eax,HTBOTTOM
    81.     .elseif eax==15h || eax==14h || eax==25h
    82.       mov eax,HTBOTTOMLEFT
    83.     .elseif eax==55h || eax==45h || eax==54h
    84.       mov eax,HTBOTTOMRIGHT
    85.     .else
    86.       mov ecx,eax
    87.       and eax,0fh
    88.       and ecx,0f0h
    89.       .if eax!=0 && ecx!=0
    90.         mov eax,HTCAPTION
    91.       .else
    92. ;        mov eax,ebx
    93.         mov eax,HTNOWHERE
    94.       .endif
    95.     .endif
    96.     jmp @f
    97.  
    98.   .elseif uMsg==WM_NCLBUTTONDBLCLK
    99.     invoke GetClassName,hWnd,addr buf,127
    100.         lea ebx,buf
    101.     invoke GetWindowLong,hWnd,GWL_STYLE
    102.     mov ecx,eax
    103.     and eax,not WS_SYSMENU
    104.     .if eax==ecx
    105.       or eax,WS_SYSMENU
    106.       mov ebx,offset _sysmenu
    107.     .endif
    108.     invoke SetWindowLong,hWnd,GWL_STYLE,eax
    109.     invoke SetWindowPos,hWnd,0,0,0,0,0,SWP_NOZORDER OR SWP_NOMOVE OR SWP_NOSIZE OR SWP_FRAMECHANGED
    110.     invoke SetWindowText,hWnd,ebx
    111.  
    112.   .else
    113.     invoke GetWindowLong,hWnd,GWL_USERDATA
    114.     push lParam
    115.     push wParam
    116.     push uMsg
    117.     push hWnd
    118.     .if eax==0
    119.       call DefWindowProc
    120.     .else
    121.       push eax
    122.       call CallWindowProc
    123.     .endif
    124.     jmp @f
    125.  
    126.   .endif
    127.   xor eax,eax
    128. @@:
    129.   ret
    130. WndProc endp
    131.  
    132. WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
    133.   local wc:WNDCLASSEX
    134.   local msg:MSG
    135.   local hWnd:HWND
    136.   local hWin:HWND
    137.  
    138.   mov wc.cbSize,sizeof WNDCLASSEX
    139.   mov wc.style,CS_DBLCLKS
    140.   mov wc.lpfnWndProc, offset WndProc
    141.   mov wc.cbClsExtra,0
    142.   mov wc.cbWndExtra,0
    143.   push hInst
    144.   pop wc.hInstance
    145.   mov wc.hbrBackground,COLOR_WINDOW+1
    146.   mov wc.lpszMenuName,0
    147.   mov wc.lpszClassName,offset _class
    148.   invoke LoadIcon,0,IDI_APPLICATION
    149.   mov wc.hIcon,eax
    150.   mov wc.hIconSm,eax
    151.   invoke LoadCursor,0,IDC_HAND
    152.   mov wc.hCursor,eax
    153.   invoke RegisterClassEx,addr wc
    154.   invoke CreateWindowEx,WS_EX_TOPMOST,offset _class,offset _class,WS_POPUP OR WS_CLIPCHILDREN,100,100,300,320,0,0,hInst,0
    155.   mov hWnd,eax
    156.   invoke ShowWindow,hWnd,CmdShow
    157.   invoke UpdateWindow,hWnd
    158.  
    159.   invoke CreateWindowEx,0,offset _static,offset _static,WS_CHILD OR WS_VISIBLE OR WS_CLIPSIBLINGS OR SS_NOTIFY,40,40,140,80,hWnd,2000,hInst,0
    160.   mov hWin,eax
    161.   invoke SetWindowLong,hWin,GWL_WNDPROC,offset WndProc
    162.   invoke SetWindowLong,hWin,GWL_USERDATA,eax
    163.  
    164.   invoke CreateWindowEx,0,offset _edit,offset _edit,WS_CHILD OR WS_VISIBLE OR WS_CLIPSIBLINGS OR ES_READONLY,40,180,140,80,hWnd,3000,hInst,0
    165.   mov hWin,eax
    166.   invoke SetWindowLong,hWin,GWL_WNDPROC,offset WndProc
    167.   invoke SetWindowLong,hWin,GWL_USERDATA,eax
    168.  
    169.   .while TRUE
    170.     invoke GetMessage,addr msg,0,0,0
    171.     .break .if (!eax)
    172.     invoke TranslateMessage,addr msg
    173.     invoke DispatchMessage,addr msg
    174.   .endw
    175.   mov eax,msg.wParam
    176.   ret
    177. WinMain endp
    178.  
    179. start:
    180.   invoke GetModuleHandle,0
    181.   invoke WinMain,eax,0,0,SW_SHOWDEFAULT
    182.   invoke ExitProcess,eax
    183. end start
    В этом примере с WM_NCHITTEST представлены три типа окон:
    простое top-level окно и дочерние Edit и Static.
    Причем для каждого из этих окон на левый даблклик повешен триггер +/-WS_SYSMENU.
    Плюс HTCLIENT заменен на HTCAPTION, драгдропа ради.

    И вот что видим:

    1) WS_SYSMENU изгоняет ресайзовые курсоры.
    2) WS_SYSMENU гробит ресайзинг top-level окна.
    3) Со Static-ом совсем хреново: вообще и не ресайзится, и не драгдропится.

    А вот в предыдущем примере с WM_SYSCOMMAND все тип-топ.
     
  16. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    kero
    Хорошие примеры, в который раз вижу отличную работу с GUI у тебя. Thx.
     
  17. kero

    kero Модератор SOURCES & 2LZ Команда форума

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
    asmfan

    Спасибо на добром слове :)
     
  18. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    kero
    Если переместить child так, чтобы его часть вышла за границу parent, то в тех участках границы где child вышел перестает работать resize parent.
     
  19. kero

    kero Модератор SOURCES & 2LZ Команда форума

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
    Да, не аккуратно как-то :)

    Но легко поправить:
    Код (Text):
    1. .const
    2. BorderWidth equ 4
    3. CornerLenght equ 20
    4. .data
    5. _class db "SizeBoxToo",0
    6. _static db "Static",0
    7. _edit db "Edit",0
    8. .data?
    9. hwnd dd ?
    10. .code
    11.  
    12. HitTest1 proc po:DWORD,mi:DWORD,ma:DWORD
    13.   mov edx,po
    14.   xor eax,eax
    15.   mov ecx,mi
    16.   cmp edx,ecx
    17.   jl @f         ; 0
    18.   inc eax
    19.   add ecx,BorderWidth
    20.   cmp edx,ecx
    21.   jl @f         ; 1
    22.   inc eax
    23.   add ecx,CornerLenght-BorderWidth
    24.   cmp edx,ecx
    25.   jl @f         ; 2
    26.   inc eax
    27.   mov ecx,ma
    28.   sub ecx,CornerLenght
    29.   cmp edx,ecx
    30.   jl @f         ; 3
    31.   inc eax
    32.   add ecx,CornerLenght-BorderWidth
    33.   cmp edx,ecx
    34.   jl @f         ; 4
    35.   inc eax
    36.   add ecx,BorderWidth
    37.   cmp edx,ecx
    38.   jl @f         ; 5
    39.   xor eax,eax   ; 0
    40. @@:
    41.   ret
    42. HitTest1 endp
    43.  
    44. HitTest2 proc hWnd:HWND
    45.   local pt:POINT
    46.   local rt:RECT
    47.   invoke GetCursorPos,addr pt
    48.   invoke GetWindowRect,hWnd,addr rt
    49.   invoke HitTest1,pt.y,rt.top,rt.bottom
    50.   push eax
    51.   invoke HitTest1,pt.x,rt.left,rt.right
    52.   shl eax,4
    53.   pop ecx
    54.   add eax,ecx
    55.   ret
    56. HitTest2 endp
    57.  
    58.  
    59. WndProc proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
    60.  
    61.   .if uMsg==WM_DESTROY
    62.     invoke PostQuitMessage,0
    63.  
    64.     .elseif uMsg==WM_NCHITTEST
    65.     invoke HitTest2,hwnd
    66.     mov cl,al
    67.     and al,0fh
    68.     and cl,0f0h
    69.     mov edx,hWnd
    70.     .if edx!=hwnd && (al==1 || al==5 || cl==10h || cl==50h)
    71.       mov eax,HTTRANSPARENT
    72.     .else
    73.       invoke DefWindowProc,hWnd,uMsg,wParam,lParam
    74.     .endif
    75.     jmp @f
    76.  
    77.   .elseif uMsg==WM_SETCURSOR
    78.     invoke HitTest2,hWnd
    79.     .if     eax==11h || eax==12h || eax==21h || eax==55h || eax==45h || eax==54h
    80.       mov eax,IDC_SIZENWSE        ; \ ; 32642
    81.     .elseif eax==15h || eax==14h || eax==25h || eax==51h || eax==41h || eax==52h  
    82.       mov eax,IDC_SIZENESW        ; / ; 32643
    83.     .elseif eax==13h || eax==53h                                                  
    84.       mov eax,IDC_SIZEWE          ; - ; 32644
    85.     .elseif eax==31h || eax==35h                                                  
    86.       mov eax,IDC_SIZENS          ; | ; 32645
    87.     .else
    88.       mov eax,IDC_ARROW               ; 32512
    89.     .endif
    90.     invoke LoadCursor,0,eax
    91.     invoke SetCursor,eax
    92.  
    93.   .elseif uMsg==WM_LBUTTONDOWN
    94.     invoke HitTest2,hWnd
    95.     .if     eax==13h
    96.       mov eax,SC_SIZE or WMSZ_LEFT            ; or 1
    97.     .elseif eax==53h
    98.       mov eax,SC_SIZE or WMSZ_RIGHT           ; or 2
    99.     .elseif eax==31h
    100.       mov eax,SC_SIZE or WMSZ_TOP             ; or 3
    101.     .elseif eax==11h || eax==21h || eax==12h
    102.       mov eax,SC_SIZE or WMSZ_TOPLEFT         ; or 4
    103.     .elseif eax==51h || eax==41h || eax==52h
    104.       mov eax,SC_SIZE or WMSZ_TOPRIGHT        ; or 5
    105.     .elseif eax==35h
    106.       mov eax,SC_SIZE or WMSZ_BOTTOM          ; or 6
    107.     .elseif eax==15h || eax==14h || eax==25h
    108.       mov eax,SC_SIZE OR WMSZ_BOTTOMLEFT      ; or 7
    109.     .elseif eax==55h || eax==45h || eax==54h
    110.       mov eax,SC_SIZE or WMSZ_BOTTOMRIGHT     ; or 8
    111.         .else
    112. ;      mov eax,SC_SIZE or 9
    113.       mov eax,SC_MOVE or 1 ; SC_MOVE or 2 ; ...
    114.     .endif
    115.     mov wParam,eax
    116.     mov uMsg,WM_SYSCOMMAND
    117. ;       invoke ReleaseCapture
    118.     jmp @@@
    119.  
    120.   .else
    121. @@@:
    122.     invoke GetWindowLong,hWnd,GWL_USERDATA
    123.     push lParam
    124.     push wParam
    125.     push uMsg
    126.     push hWnd
    127.     .if eax==0
    128.       call DefWindowProc
    129.     .else
    130.       push eax
    131.       call CallWindowProc
    132.     .endif
    133.     jmp @f
    134.  
    135.   .endif
    136.   xor eax,eax
    137. @@:
    138.   ret
    139. WndProc endp
    140.  
    141. WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
    142.   local wc:WNDCLASSEX
    143.   local msg:MSG
    144.   local hWnd:HWND
    145.  
    146.   mov wc.cbSize,sizeof WNDCLASSEX
    147.   mov wc.style,CS_DBLCLKS
    148.   mov wc.lpfnWndProc, offset WndProc
    149.   mov wc.cbClsExtra,0
    150.   mov wc.cbWndExtra,0
    151.   push hInst
    152.   pop wc.hInstance
    153.   mov wc.hbrBackground,COLOR_WINDOW+1
    154.   mov wc.lpszMenuName,0
    155.   mov wc.lpszClassName,offset _class
    156.   invoke LoadIcon,0,IDI_APPLICATION
    157.   mov wc.hIcon,eax
    158.   mov wc.hIconSm,eax
    159.   invoke LoadCursor,0,IDC_HAND
    160.   mov wc.hCursor,eax
    161.   invoke RegisterClassEx,addr wc
    162.   invoke CreateWindowEx,WS_EX_TOPMOST,offset _class,offset _class,WS_POPUP OR WS_CLIPCHILDREN OR WS_SYSMENU,100,100,300,320,0,0,hInst,0
    163.   mov hwnd,eax
    164.   invoke ShowWindow,hwnd,CmdShow
    165.   invoke UpdateWindow,hwnd
    166.  
    167.   invoke CreateWindowEx,0,offset _static,offset _static,WS_CHILD OR WS_VISIBLE OR WS_CLIPSIBLINGS OR SS_NOTIFY,40,40,140,80,hwnd,2000,hInst,0
    168.   mov hWnd,eax
    169.   invoke SetWindowLong,hWnd,GWL_WNDPROC,offset WndProc
    170.   invoke SetWindowLong,hWnd,GWL_USERDATA,eax
    171.  
    172.   invoke CreateWindowEx,0,offset _edit,offset _edit,WS_CHILD OR WS_VISIBLE OR WS_CLIPSIBLINGS OR ES_READONLY,40,180,140,80,hwnd,3000,hInst,0
    173.   mov hWnd,eax
    174.   invoke SetWindowLong,hWnd,GWL_WNDPROC,offset WndProc
    175.   invoke SetWindowLong,hWnd,GWL_USERDATA,eax
    176.  
    177.   .while TRUE
    178.     invoke GetMessage,addr msg,0,0,0
    179.     .break .if (!eax)
    180.     invoke TranslateMessage,addr msg
    181.     invoke DispatchMessage,addr msg
    182.   .endw
    183.   mov eax,msg.wParam
    184.   ret
    185. WinMain endp
    186.  
    187. start:
    188.   invoke GetModuleHandle,0
    189.   invoke WinMain,eax,0,0,SW_SHOWDEFAULT
    190.   invoke ExitProcess,eax
    191. end start
     
  20. kero

    kero Модератор SOURCES & 2LZ Команда форума

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
    WM_NCHITTEST-less

    Оказывается, слова AsmGuru62 -

    - чистая правда, если вместо WM_NCHITTEST читать WM_SETCURSOR :)

    Код (Text):
    1. .const
    2. BorderWidth equ 4
    3. CornerLenght equ 20
    4. .data
    5. _class db "SizeBoxToo",0
    6. _static db "Static",0
    7. .data?
    8. hwnd dd ?
    9. .code
    10.  
    11. HitTest1 proc po:DWORD,mi:DWORD,ma:DWORD
    12.   mov edx,po
    13.   xor eax,eax
    14.   mov ecx,mi
    15.   cmp edx,ecx
    16.   jl @f         ; 0
    17.   inc eax
    18.   add ecx,BorderWidth
    19.   cmp edx,ecx
    20.   jl @f         ; 1
    21.   inc eax
    22.   add ecx,CornerLenght-BorderWidth
    23.   cmp edx,ecx
    24.   jl @f         ; 2
    25.   inc eax
    26.   mov ecx,ma
    27.   sub ecx,CornerLenght
    28.   cmp edx,ecx
    29.   jl @f         ; 3
    30.   inc eax
    31.   add ecx,CornerLenght-BorderWidth
    32.   cmp edx,ecx
    33.   jl @f         ; 4
    34.   inc eax
    35.   add ecx,BorderWidth
    36.   cmp edx,ecx
    37.   jl @f         ; 5
    38.   xor eax,eax   ; 0
    39. @@:
    40.   ret
    41. HitTest1 endp
    42.  
    43. HitTest2 proc hWnd:HWND
    44.   local pt:POINT
    45.   local rt:RECT
    46.   invoke GetCursorPos,addr pt
    47.   invoke GetWindowRect,hWnd,addr rt
    48.   invoke HitTest1,pt.y,rt.top,rt.bottom
    49.   push eax
    50.   invoke HitTest1,pt.x,rt.left,rt.right
    51.   shl eax,4
    52.   pop ecx
    53.   add eax,ecx
    54.   ret
    55. HitTest2 endp
    56.  
    57.  
    58. WndProc proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
    59.  
    60.   .if uMsg==WM_DESTROY
    61.     invoke PostQuitMessage,0
    62.  
    63.   .elseif uMsg==WM_SETCURSOR
    64.     invoke HitTest2,hwnd
    65.     mov cl,al
    66.     and al,0fh
    67.     and cl,0f0h
    68.     mov edx,hWnd
    69.     .if edx!=hwnd && (al==1 || al==5 || cl==10h || cl==50h)
    70.       mov edx,hwnd
    71.       mov hWnd,edx
    72.     .endif
    73.     invoke HitTest2,hWnd
    74.     mov ecx,lParam
    75.     mov edx,ecx
    76.     shr edx,16
    77.     .if dx==WM_MOUSEMOVE
    78.       .if     eax==11h || eax==12h || eax==21h || eax==55h || eax==45h || eax==54h
    79.         mov eax,IDC_SIZENWSE        ; \ ; 32642
    80.       .elseif eax==15h || eax==14h || eax==25h || eax==51h || eax==41h || eax==52h  
    81.         mov eax,IDC_SIZENESW        ; / ; 32643
    82.       .elseif eax==13h || eax==53h                                                  
    83.         mov eax,IDC_SIZEWE          ; - ; 32644
    84.       .elseif eax==31h || eax==35h                                                  
    85.         mov eax,IDC_SIZENS          ; | ; 32645
    86.       .else
    87.         mov eax,IDC_ARROW               ; 32512
    88.       .endif
    89.       invoke LoadCursor,0,eax
    90.       invoke SetCursor,eax
    91.     .elseif dx==WM_LBUTTONDOWN
    92.       .if     eax==13h
    93.         mov eax,SC_SIZE or WMSZ_LEFT            ; or 1
    94.       .elseif eax==53h
    95.         mov eax,SC_SIZE or WMSZ_RIGHT           ; or 2
    96.       .elseif eax==31h
    97.         mov eax,SC_SIZE or WMSZ_TOP             ; or 3
    98.       .elseif eax==11h || eax==21h || eax==12h
    99.         mov eax,SC_SIZE or WMSZ_TOPLEFT         ; or 4
    100.       .elseif eax==51h || eax==41h || eax==52h
    101.         mov eax,SC_SIZE or WMSZ_TOPRIGHT        ; or 5
    102.       .elseif eax==35h
    103.         mov eax,SC_SIZE or WMSZ_BOTTOM          ; or 6
    104.       .elseif eax==15h || eax==14h || eax==25h
    105.         mov eax,SC_SIZE or WMSZ_BOTTOMLEFT      ; or 7
    106.       .elseif eax==55h || eax==45h || eax==54h
    107.         mov eax,SC_SIZE or WMSZ_BOTTOMRIGHT     ; or 8
    108.           .else
    109.         mov eax,SC_SIZE or 9
    110. ;        mov eax,SC_MOVE or 1
    111. ;        mov eax,SC_MOVE or 2
    112.       .endif
    113.       mov wParam,eax
    114.       mov uMsg,WM_SYSCOMMAND
    115.       jmp @f
    116.     .else
    117.       jmp @f
    118.     .endif
    119.   .else
    120. @@:
    121.     invoke GetWindowLong,hWnd,GWL_USERDATA
    122.     push lParam
    123.     push wParam
    124.     push uMsg
    125.     push hWnd
    126.     .if eax==0
    127.       call DefWindowProc
    128.     .else
    129.       push eax
    130.       call CallWindowProc
    131.     .endif
    132.     jmp @f
    133.   .endif
    134.   xor eax,eax
    135. @@:
    136.   ret
    137. WndProc endp
    138.  
    139. SubClass proc hWnd:HWND
    140.   invoke SetWindowLong,hWnd,GWL_WNDPROC,offset WndProc
    141.   invoke SetWindowLong,hWnd,GWL_USERDATA,eax
    142.   ret
    143. SubClass endp
    144.  
    145. WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
    146.   local wc:WNDCLASSEX
    147.   local msg:MSG
    148.   mov wc.cbSize,sizeof WNDCLASSEX
    149.   mov wc.style,CS_DBLCLKS
    150.   mov wc.lpfnWndProc, offset WndProc
    151.   mov wc.cbClsExtra,0
    152.   mov wc.cbWndExtra,0
    153.   push hInst
    154.   pop wc.hInstance
    155.   mov wc.hbrBackground,COLOR_WINDOW+1
    156.   mov wc.lpszMenuName,0
    157.   mov wc.lpszClassName,offset _class
    158.   invoke LoadIcon,0,IDI_APPLICATION
    159.   mov wc.hIcon,eax
    160.   mov wc.hIconSm,eax
    161.   invoke LoadCursor,0,IDC_HAND
    162.   mov wc.hCursor,eax
    163.   invoke RegisterClassEx,addr wc
    164.  
    165.   invoke CreateWindowEx,WS_EX_TOPMOST,offset _class,offset _class,WS_POPUP OR WS_CLIPCHILDREN OR WS_SYSMENU,100,100,310,370,0,0,hInst,0
    166.   mov hwnd,eax
    167.   invoke ShowWindow,hwnd,CmdShow
    168.   invoke UpdateWindow,hwnd
    169.  
    170.   invoke CreateWindowEx,0,offset _class,offset _class, WS_CHILD OR WS_VISIBLE OR WS_CLIPSIBLINGS OR WS_CLIPCHILDREN OR WS_SYSMENU OR WS_CAPTION,40,160,210,160,hwnd,2000,hInst,0
    171.   invoke CreateWindowEx,0,offset _static,offset _static,WS_CHILD OR WS_VISIBLE OR WS_CLIPSIBLINGS OR SS_NOTIFY, 20,20,140,80,eax,2001,hInst,0
    172.   invoke SubClass,eax
    173.   invoke CreateWindowEx,0,offset _static,offset _static,WS_CHILD OR WS_VISIBLE OR WS_CLIPSIBLINGS OR SS_NOTIFY,40,40,140,80,hwnd,2002,hInst,0
    174.   invoke SubClass,eax
    175.  
    176.   .while TRUE
    177.     invoke GetMessage,addr msg,0,0,0
    178.     .break .if (!eax)
    179.     invoke TranslateMessage,addr msg
    180.     invoke DispatchMessage,addr msg
    181.   .endw
    182.   mov eax,msg.wParam
    183.   ret
    184. WinMain endp
    185.  
    186. start:
    187.   invoke GetModuleHandle,0
    188.   invoke WinMain,eax,0,0,SW_SHOWDEFAULT
    189.   invoke ExitProcess,eax
    190. end start
    Между прочим,
    1) драгдроп поддерживается недокументированной константой SC_SIZE+9,
    поскольку SC_MOVE+1/SC_MOVE+2 в этом примере почему-то не работают,
    2) а поправка q_q реализована иначе, чем в предыдущем примере.