Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 10.03.2016, 16:27   #1
BLACK_RAIN
Форумчанин
 
Регистрация: 13.02.2012
Сообщений: 867
По умолчанию таскать static по окну мышкой

Здравствуйте.
Нужно перетаскивать контрол static по окну мышкой.
Код:
nx , ny , oldx, oldy: smallint;


    WM_LBUTTONDOWN:
    begin
      oldx := loword(Lpar);
      oldy := HiWord(Lpar);
      drag := True;
      SetCapture(wnd);
    end;

    WM_LBUTTONUP:
    begin
      drag := False;
      ReleaseCapture;
    end;

    WM_MOUSEMOVE:
    begin
      if drag then
      begin
        x := loword(Lpar);
        y := HiWord(Lpar);
        x2 := nx + x - oldx;
        y2 := ny + y - oldy;
        oldx := x;
        oldy := y;
        nx := x2;
        ny := y2;
        MoveWindow(w3,x2,y2,100,100,True);
        settext(form1,'x='+ IntToStr(x2)+ ',y='+ IntToStr(y2));
      end;
    end;
nx, ny - позиция статика. Изначально 0,0
Это работает, если события принимает парент статика. Если переопределить оконную процедуру статика и принимать события в ней, то WM_MOUSEMOVE начинает приходить не только при движении мыши, а постоянно. При этом, значения x2,y2 постоянно меняются и статик перемещается не туда. Как это исправить?
p.s. Решено. Можете удалить

Последний раз редактировалось BLACK_RAIN; 11.03.2016 в 11:11.
BLACK_RAIN вне форума Ответить с цитированием
Старый 10.03.2016, 21:31   #2
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

А чему равны nx и ny?
Далее, зачем так сложно, прочитайте про WM_NCHITTEST и результат HTCAPTION.
Правда для контролов не пробовал но окна таскаются на ура.
waleri вне форума Ответить с цитированием
Старый 11.03.2016, 07:50   #3
BLACK_RAIN
Форумчанин
 
Регистрация: 13.02.2012
Сообщений: 867
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
А чему равны nx и ny?
Далее, зачем так сложно, прочитайте про WM_NCHITTEST и результат HTCAPTION.
Правда для контролов не пробовал но окна таскаются на ура.
WM_NCHITTEST и HTCAPTION не использую потому, что при перетаскивании нужно выполнять еще другие действия.
nx,ny изначально равны 0,0 и таскаемый статик находится в координате 0,0.
И еще есть такой глюк: если зажать ЛКМ на статике и шевельнуть мышь, то WM_MOUSEMOVE начинает приходить постоянно, пока ЛКМ нажата. Так ведь не должно быть??? почему это происходит?
Добавлено
Сейчас проверил такую штуку: если браться не за сам статик, а за главное окно, то статик таскается нормально. То есть, если события WM_LBUTTONDOWN,WM_LBUTTONUP,WM_MOUS EMOVE будет принимать не сам таскаемый статик, а главное окно программы или другой child. А если их принимает сам статик, то получается вот что:
[SPOILER]
[/SPOILER]

То есть, происходит примерно следующее: зажимаем ЛКМ и немного сдвигаем мышь (и больше ее не двигаем, но продолжаем держать ЛКМ). WM_MOUSEMOVE начинает приходить постоянно, в цикле. Как видим на скриншоте, WM_MOUSEMOVE пришел 4527 раз. Это за 4 секунды и мышку я почти не двигал. А так же видим, что переменные x2,y2 постоянно принимают разные значения. Если убрать MoveWindow, то всё вроде бы как нормально с цифрами становится. Но статик-то не перемещается.

Последний раз редактировалось BLACK_RAIN; 11.03.2016 в 10:53.
BLACK_RAIN вне форума Ответить с цитированием
Старый 11.03.2016, 11:15   #4
BLACK_RAIN
Форумчанин
 
Регистрация: 13.02.2012
Сообщений: 867
По умолчанию

Решено! Просто не нужно добавлять стиль SS_NOTIFY, если делаешь сабклассинг. Теперь учту.

Ну вот как всегда. Одна проблема решилась, вторая появилась.
Нужно перетаскивать статик, который находится в классе. Вот класс:
Код:
type
  testclass = class(TObject)
    public
      w1 : HWND;
//      w2 : HWND;
      dc1 : HDC;
//      dc2 : HDC;
      brush1 : HBRUSH;
//      brush2 : HBRUSH;
      oldx  : SmallInt;
      oldy : SmallInt;
      drag : Boolean;
      nx : SmallInt;
      ny : SmallInt;
      nw : SmallInt;
      nh : SmallInt;
      constructor Create(handle : HWND);
      destructor destroy;
      procedure draw;
end;
Динамически создается несколько таких классов и делается сабклассинг окна w1. Проблема в том, что окну не приходят сообщения типа WM_LBUTTON*, WM_RBUTTON*, WM_MOUSEMOVE, если у окна w1 нет стиля SS_NOTIFY. А с ним получается рекурсия. Что делать?
Очень не хочется юзать WM_NCHITTEST.

Последний раз редактировалось BLACK_RAIN; 11.03.2016 в 12:45.
BLACK_RAIN вне форума Ответить с цитированием
Старый 12.03.2016, 09:46   #5
BLACK_RAIN
Форумчанин
 
Регистрация: 13.02.2012
Сообщений: 867
По умолчанию

Задача простая. Помогите же.
Имеем класс, в классе статик. Делаем сабклассинг статика - ему не приходят события мыши. Если брать такой же статик вне класса, то ему приходят. Если ставить стиль SS_NOTIFY, тогда получается рекурсия в событии WM_MOUSEMOVE.
Как это решить без использования WM_NCHITTEST?

не пойму, что делать с WM_NCHITTEST. Пишут, что нужно отправить Result := SendMessage(wnd,WM_NCHITTEST,HTCAPT ION,Lpar); по клику мыши. Но у меня событие WM_LBUTTONDOWN не приходит. А если с SS_NOTIFY, то рекурсия получается.
Объясните хотя-бы, почему и откуда берётся рекурсия?

Последний раз редактировалось BLACK_RAIN; 12.03.2016 в 16:09.
BLACK_RAIN вне форума Ответить с цитированием
Старый 13.03.2016, 14:57   #6
BLACK_RAIN
Форумчанин
 
Регистрация: 13.02.2012
Сообщений: 867
По умолчанию

если события от мыши не приходят, то способ с WM_NCHITTEST использовать не получится, верно? не молчите
BLACK_RAIN вне форума Ответить с цитированием
Старый 13.03.2016, 16:31   #7
BLACK_RAIN
Форумчанин
 
Регистрация: 13.02.2012
Сообщений: 867
По умолчанию

Теперь код из первого поста опять перестал работать. Даже если статик находится вне класса. WM_MOUSEMOVE приходит рекурсивно. В посте №4 я написал, что проблема решена. Нужно убрать стиль SS_NOTIFY. Но теперь это перестало работать!
Код:
      w3 := CreateWindowEx(WS_EX_CLIENTEDGE,'static','jjjj',
                    WS_CHILD or WS_VISIBLE or SS_BITMAP or SS_NOTIFY,
                        200,0,100,100,wnd,0,Hinstance,nil);

          oldproc2 := SetWindowLong(w3,GWL_WNDPROC,LongInt(@Proc2));
так рекурсия.
Код:
      w3 := CreateWindowEx(WS_EX_CLIENTEDGE,'static','jjjj',
                    WS_CHILD or WS_VISIBLE or SS_BITMAP,
                        200,0,100,100,wnd,0,Hinstance,nil);
          oldproc2 := SetWindowLong(w3,GWL_WNDPROC,LongInt(@Proc2));
а так события от мыши просто не приходят!
BLACK_RAIN вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
static и non-static context kos1nus Общие вопросы по Java, Java SE, Kotlin 1 17.07.2013 00:10
Не таскать с собой libmySQL.dll Synapse C/C++ Базы данных 2 16.07.2012 04:23
Рисование STATIC мышкой Sylvos Win Api 1 23.02.2012 06:27
static Gen_r_questions PHP 7 05.04.2011 15:12
Таскать фигуру мышкой Poseydon Общие вопросы Delphi 4 07.08.2008 12:36