RaCad.dll сделал лучше, но с багом. Не могу его устранить.

Тема в разделе "WASM.ASSEMBLER", создана пользователем God_Father, 22 ноя 2008.

  1. God_Father

    God_Father New Member

    Публикаций:
    0
    Регистрация:
    5 авг 2007
    Сообщения:
    99
    Дело было так. Решил я улучшить контрол, находящийсяв RaCad.dll, чтобы при нажатии на среднюю кнопку мыши происходил
    "захват" изображения, а при отпускании соответственно ставился скроллбар и скроллировалось изображение. В дальнейшем я хочу сделать увеличение-уменьшение скроллированием.
    Но обнаружил такой баг. При уменьшении изображения и "захвате" его оно начинает "ненормально " двигаться и программа падает.

    дописывал в RaCad я вот что.
    .elseif eax==WM_MOUSEMOVE
    ;int 3
    mov eax,wParam
    .if eax==MK_MBUTTON
    invoke GetCursor
    .if (eax == tempcursor)
    .elseif
    ;invoke LoadCursor,NULL,IDC_SIZEALL
    invoke SetCursor,tempcursor
    .endif
    m_m:
    invoke GetWindowLong,hWin,0
    mov ebx,eax
    xor ecx,ecx
    xor edx,edx
    mov eax,cn.cur.x

    sub eax,oldpointdrag.x ;eax-разница иксов
    neg eax ; oldpointdrag.x-cn.cur.x
    add eax,counterx ;oldpointdrag.x-cn.cur.x+counter
    mov counterx,eax
    mov sinf.cbSize,sizeof sinf
    mov sinf.fMask,SIF_POS
    mov eax,counterx
    add [ebx].CADMEM.scroll.x,eax
    neg eax
    invoke ScrollWindow,hWin,eax,0,NULL,NULL
    xor edx,edx
    xor ecx,ecx
    mov eax,counterx
    mov eax,[ebx].CADMEM.scroll.x
    call ZoomDiv
    mov sinf.nPos,eax
    ;int 3
    invoke SetScrollInfo,hWin,SB_HORZ,addr sinf,TRUE
    invoke UpdateWindow,hWin
    ;------------------------------------------------------------------
    mov eax,cn.cur.y

    sub eax,oldpointdrag.y ;eax-разница иксов
    neg eax ; oldpointdrag.x-cn.cur.x
    push eax
    invoke GetWindowLong,hWin,0
    mov ebx,eax
    pop eax
    add eax,countery ;oldpointdrag.x-cn.cur.x+counter
    mov countery,eax
    mov sinf.cbSize,sizeof sinf
    mov sinf.fMask,SIF_POS
    mov eax,countery
    add [ebx].CADMEM.scroll.y,eax
    ;int 3
    neg eax
    invoke ScrollWindow,hWin,0,eax,NULL,NULL
    xor edx,edx
    xor ecx,ecx
    mov eax,countery
    mov eax,[ebx].CADMEM.scroll.y
    call ZoomDiv
    mov sinf.nPos,eax
    ;int 3
    invoke SetScrollInfo,hWin,SB_VERT,addr sinf,TRUE
    invoke UpdateWindow,hWin
    ;------------------------------------------------------------------
    mov eax,cn.cur.x
    mov oldpointdrag.x,eax
    mov eax,cn.cur.y
    mov oldpointdrag.y,eax
    ;------------------------------------------------------------------
    .endif

    баг проявляется когда ставится масштаб 0,6 и программа падает когда ставится масштаб 0,4 и наже.
    Исходник переделанный приаттачил к сообщению.
     
  2. God_Father

    God_Father New Member

    Публикаций:
    0
    Регистрация:
    5 авг 2007
    Сообщения:
    99
    SimCad который юзает RaCad.dll в архиве
     
  3. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    God_Father
    > Решил я улучшить контрол, находящийсяв RaCad.dll ... программа падает
    Переполнение при делении.
    Где можно посмотреть на оригинальный, желательно код, RACad?
     
  4. Jupiter

    Jupiter Jupiter

    Публикаций:
    0
    Регистрация:
    12 авг 2004
    Сообщения:
    532
    Адрес:
    Russia
    q_q
    оригинальные исходники лежат на сайте RadAsm в разделе projects / custom controls
     
  5. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
  6. God_Father

    God_Father New Member

    Публикаций:
    0
    Регистрация:
    5 авг 2007
    Сообщения:
    99
    Оригинальный код лежит здесь:
    http://www.radasm.com/projects/SimCad.zip
     
  7. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    God_Father
    > Оригинальный код
    Посмотрел. Imho там (в оригинальной версии) кривой скроллинг.
    Поясню. Выставляю коэффициент zoom'а 21.20, перемещаю thumb'ы обоих scrollbar'ов, вправо вниз, курсор мышки веду к позиции (20000,20000), это максимум, и увожу за пределы cad-окна, затем , PgUp'ом уменьшаю zoom до 0.20, в результате координаты курсора становятся (25695,24140), что явно больше максимума и видна белая область за краем холста, аккуратно навожу курсор мышки на каждый из thumb'ов, click'аю по ним, в результате белая область пропадает, а нижний правый угол холста оказывается в нижнем правом углу cad-окна.

    + в SimCad не устанавливает фокус на cad-окно. Твое решение этой проблемой в обработчике WM_PAINT в корне не правильно. Необходимо, добавлять обработку WM_SETFOCUS в SimCad.

    > Решил я улучшить контрол ... сделать увеличение-уменьшение скроллированием.
    Достаточно в оригинальную версию добавить
    Код (Text):
    1. ...
    2. CadProc proc uses ebx,hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
    3. ...
    4.     .elseif eax==WM_MOUSEWHEEL
    5.         mov eax,wParam
    6.         or  eax,eax
    7.         mov eax,CM_ZOOMOUT
    8.         jns short @F
    9.         mov eax,CM_ZOOMIN
    10.     @@: invoke  SendMessage, hWin, eax, 0, 0
    11. ...
    разумеется перед этим решив вопрос с фокусом.

    Что касается прокрутки холста при нажатой средней кнопки мышки, то для начала необходимо сделать корректную обработку cad-окном WM_SIZE, WM_HSCROLL и WM_VSCROLL.

    edit(add)
    Пример правильной обработки WM_SIZE, WM_HSCROLL и WM_VSCROLL можно посмотреть у mspaint. Сделай холст побольше, меняй размеры окна, если холст полностью виден, то полосок прокрутки нет. Если холст не помещается в окне, и полоску прокрутки поместить в крайнее нижнее/правое положение и начать увеличивать размер окна, то холст прилипнет к нижней/правой границе до тех пор пока, не покажется весь, а потом полоска прокрутки пропадет.
     
  8. God_Father

    God_Father New Member

    Публикаций:
    0
    Регистрация:
    5 авг 2007
    Сообщения:
    99
    А примеры программ, где это правильно отбражается с исходниками есть?
    А обработка WM_SETFOCUS здесь нужно выставлять фокус окну функой SetFocus
    Я правильно понял?
     
  9. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    God_Father
    > А обработка WM_SETFOCUS здесь нужно выставлять фокус окну функой SetFocus
    Если я правильно тебя понял, то ты правильно меня понял. На всякий случай
    Код (Text):
    1. ;; SimCad.asm...
    2. WndProc proc uses ebx,hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
    3. ...
    4.     mov eax,uMsg
    5.     .if eax==WM_INITDIALOG
    6. ...
    7.     .elseif eax==WM_SETFOCUS
    8.         invoke  IsWindow, hCad
    9.         .if eax != 0
    10.             invoke  SetFocus, hCad
    11.         .endif
    12. ...
    > А примеры программ, где это правильно отбражается с исходниками есть?
    см. аттач.
     
  10. God_Father

    God_Father New Member

    Публикаций:
    0
    Регистрация:
    5 авг 2007
    Сообщения:
    99
    q_q в твоем примере когда окно растянишь на весь экран то область где должен быть скролл становится серой. Как сделать так, чтобы он исчезал?
     
  11. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    God_Father
    Например
    Код (Text):
    1. ...
    2.   wndproc proc uses ebx edi esi, hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
    3. ...
    4.     .elseif uMsg == WM_SIZE
    5. ...
    6.           invoke SetScrollInfo, hWnd, SB_HORZ, addr sci, TRUE
    7. ;;--          mov eax,ESB_ENABLE_BOTH
    8.           mov eax,1
    9.         .else
    10. ;;--          mov eax,ESB_DISABLE_BOTH
    11.           xor eax,eax
    12.         .endif
    13. ;;--        invoke EnableScrollBar, hWnd, SB_HORZ, eax
    14.     invoke ShowScrollBar, hWnd, SB_HORZ, eax
    15. ...
    16.           invoke SetScrollInfo, hWnd, SB_VERT, addr sci, TRUE
    17. ;;--          mov eax,ESB_ENABLE_BOTH
    18.           mov eax,1
    19.         .else
    20. ;;--          mov eax,ESB_DISABLE_BOTH
    21.           xor eax,eax
    22.         .endif
    23. ;;--        invoke EnableScrollBar, hWnd, SB_VERT, eax
    24.         invoke ShowScrollBar, hWnd, SB_VERT, eax
    25. ...
     
  12. God_Father

    God_Father New Member

    Публикаций:
    0
    Регистрация:
    5 авг 2007
    Сообщения:
    99
    А какое сообщение нужно обрабатывать, когда прокруиваешь колесиком мымши находящемся на полосе прокрутки скроллбара, чтобы изображение прокручивалось соответственно горизонтально, и вертикально.
    Такой механизм прокрутки работает в Operе. И какое сообщение ловить, чтоб перерисовать скроллбар как хочется?
     
  13. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    God_Father
    WM_MOUSEWHEEL, только оно почему то приходит только в главное окно программы, но в твоём случае это как раз не принципиально - просто определяй по координатам (lparam) над чем крутится колёсико и посылай соответствующие команды соответствующим контролам.

    ты это про SetScrollInfo? или про возможность заменить скроллбар своей картинкой?
     
  14. God_Father

    God_Father New Member

    Публикаций:
    0
    Регистрация:
    5 авг 2007
    Сообщения:
    99
    И про то и про то оптом :)