Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Дочерние окна и рисование на них 
V
    Опции темы
namervasek
Дата 20.7.2009, 16:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 3.12.2007

Репутация: нет
Всего: нет



Всем привет!  Суть проги.... рисую в одном дочернем окне фигуру и пытаюсь перенести эту фигуру в другое дочернее окно путем перетаскивание... Но проблема втом что не знаю как в этом случае рисовать. Тоесть тоскать фигуру внутри окна где она рисуется получается а сделать так что фигура еще могла бы на другие области главного окна перестаскиваться неполучается. 
Поскажите плиз как это реализовать.
Код того что сделал снизу.


Это сообщение отредактировал(а) namervasek - 20.7.2009, 16:17

Присоединённый файл ( Кол-во скачиваний: 7 )
Присоединённый файл  poisk_pyti.cpp 9,32 Kb
PM MAIL   Вверх
Cheloveck
Дата 20.7.2009, 16:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

Репутация: 1
Всего: 32



Очень много букаф в прикреплённом файле, читать ооочень не хочется. Я когда-то раньше рисовал прямо на форме, а потом плюнул на всё и для каждой картиночки, что мне нужна, создаю статик. На статике рисую всё, что надо. Соответственно ты можешь создать статик, на нём рисовать свою фигуру. Контекст, на котором рисуешь где-то определён, так, что к нему есть всегда доступ. Когда нужно перетащить статик на другое окно, то убиваешь его (статик) на текущем окне и создаёшь на нужном с контекстом, что сохранил. Не знаю на сколько это правильно, но это первое, что в голову пришло.


--------------------
user posted image
PM Jabber   Вверх
GremlinProg
Дата 20.7.2009, 16:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата

Дочерние окна и рисование на них

тогда может: Дочерние окна и рисование между ними?
Цитата(namervasek @  20.7.2009,  18:16 Найти цитируемый пост)
Тоесть тоскать фигуру внутри окна где она рисуется получается а сделать так что фигура еще могла бы на другие области главного окна перестаскиваться неполучается

не получается рисовать фигуру (при таскании) на главном окне, или в соседнем дочернем окне?
или не получается просто передать фигуру в соседнее окно?
что конкретно не получается?

код лучше оформить и показать в соответствующих тегах,
еще лучше показать скриншоты (такие задачи плохо воспринимаются на словах без наглядных экспонатов)


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
namervasek
Дата 20.7.2009, 21:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 3.12.2007

Репутация: нет
Всего: нет



Цитата

не получается рисовать фигуру (при таскании) на главном окне, или в соседнем дочернем окне?
или не получается просто передать фигуру в соседнее окно?
что конкретно не получается?

Эм.. Ну на скринах так:

Вот сначала я нарисовал фигуру(в правом маленьком окошке)
user posted image
Потом после клика мышкой по фигуре я её перетаскиваю(красным перемещеная фигура )
user posted image
Но если область фигуры заходит за пределы маленького окна то она не прорисовыватеся полностью, прорисовывается только часть внутри маленького окна(опять же выделено красным)
user posted image

Нужно же что бы я мог таскать мышой фигуру по все области главного окна.

По коду: там собствено показывать то не чего так как в нем сейчас только рисование фигуры и перетаскивание внутри маленького окна
Ну на всякий случай вот главные процедуры(это процедуры обрабытывающие сообщения маленького окна): 
Код

void Image_OnMouseDown(HWND hwnd, int x,int y)
{
  static POINT point_b={-1,-1};  
  
  if (Mode==1)
  {
    if (p_mas==NULL) 
    { 
      p_massize++;
      p_mas=(POINT*)malloc(sizeof(POINT));
      p_mas[0].x=x;
      p_mas[0].y=y;      
    }
    else 
    {
      if (x>=(p_mas[0].x-4) && x<=(p_mas[0].x+4) && y>=(p_mas[0].y-4) && y<=(p_mas[0].y+4))
      {
          Mode=EndPaintMode;
          Region=CreatePolygonRgn(p_mas,p_massize,WINDING);
          InvalidateRect(hwnd,NULL,TRUE);
          UpdateWindow(hwnd_image);

      }
      else
      {
          p_massize++;
          p_mas=(POINT *) realloc(p_mas,sizeof(POINT)*p_massize);
          p_mas[p_massize-1].x=x;
          p_mas[p_massize-1].y=y;

      }  
    }
  }
  if (Mode==3)
  { 
     if (PtInRegion(Region,x,y)) 
     {
         Mode=MoveMode;
         old_point_a.x=x;
         old_point_a.y=y;
     }
  }

}

void Image_OnMouseMove(HWND hwnd, int x,int y, WPARAM wparam)
{
  static POINT old_point_b={0,0};
  static POINT old_point_c={0,0};
  static bool f=false;  
  static bool f1=false;

  if (p_mas!=NULL && Mode==1 ) 
  {
      HDC hdc = GetDC(hwnd);      
      Ellipse(hdc,p_mas[0].x-4, p_mas[0].y-4, p_mas[0].x+4, p_mas[0].y+4);      
      SetROP2(hdc, R2_NOTXORPEN);

      if (f)
      {
          MoveToEx(hdc,p_mas[p_massize-1].x, p_mas[p_massize-1].y, (LPPOINT) NULL);
          LineTo(hdc, old_point_b.x, old_point_b.y);
      }      
      
      MoveToEx(hdc,p_mas[p_massize-1].x, p_mas[p_massize-1].y, (LPPOINT) NULL);
      LineTo(hdc, x, y); 


      f=true;
      old_point_b.x=x;
      old_point_b.y=y;
      
      ReleaseDC(hwnd, hdc);  
  }
  else
  {
      old_point_b.x=0;
      old_point_b.y=0;
      f=false;


  }
  if (p_mas==NULL)
  {
     old_point_c.x=0;
      old_point_c.y=0;
      f1=false;
  }
  if (Mode==2)
  {
      HDC hdc = GetDC(hwnd);
      SetROP2(hdc, R2_NOTXORPEN);
      int i;

        
      if (f1)
      {
       
          for (i = 0; i <=p_massize-2; i++)
          {
          MoveToEx(hdc,p_mas[i].x+(old_point_c.x), p_mas[i].y+(old_point_c.y), (LPPOINT) NULL);
          LineTo(hdc,p_mas[i+1].x+old_point_c.x, p_mas[i+1].y+old_point_c.y);
          }
          
          MoveToEx(hdc,p_mas[i].x+old_point_c.x, p_mas[i].y+old_point_c.y, (LPPOINT) NULL);
          LineTo(hdc,p_mas[0].x+old_point_c.x, p_mas[0].y+old_point_c.y); 
      
      }  
      
      for (i = 0; i <=p_massize-2; i++)
      {
          MoveToEx(hdc,p_mas[i].x+(x-old_point_a.x), p_mas[i].y+(y-old_point_a.y), (LPPOINT) NULL);
          LineTo(hdc,p_mas[i+1].x+(x-old_point_a.x), p_mas[i+1].y+(y-old_point_a.y));

      }
      
      MoveToEx(hdc,p_mas[i].x+(x-old_point_a.x), p_mas[i].y+(y-old_point_a.y), (LPPOINT) NULL);
      LineTo(hdc,p_mas[0].x+(x-old_point_a.x), p_mas[0].y+(y-old_point_a.y)); 
        

       
      ReleaseDC(hwnd, hdc);
         
      f1=true;
      old_point_c.x=x-old_point_a.x;
      old_point_c.y=y-old_point_a.y;

      
  }

}


void Image_OnPaint(HWND hwnd)
{ 
  int i=0; 
  
  
  if (p_mas!=NULL && Mode==3)
  {
       HDC hdc = GetDC(hwnd);
       
       for (i = 0; i <=p_massize-2; i++)
       {
          MoveToEx(hdc,p_mas[i].x, p_mas[i].y, (LPPOINT) NULL);
          LineTo(hdc,p_mas[i+1].x, p_mas[i+1].y);

       }
       MoveToEx(hdc,p_mas[i].x, p_mas[i].y, (LPPOINT) NULL);
       LineTo(hdc,p_mas[0].x, p_mas[0].y); 

       
       ReleaseDC(hwnd, hdc);
       
  }
  

}


PM MAIL   Вверх
GremlinProg
Дата 21.7.2009, 14:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



ну вот, хорошее описание, все бы так делали,
больше бы получали ответов по-существу

я не понял только одного: зачем создавать объект в маленьком окне, чтобы перенести его в большое?
не проще создавать в большом окне?

1. "захват объекта"
чтобы таскать объект независимо от того, в каком окне он находится,
нужно на WM_LBUTTONDOWN (при захвате фигуры) вызвать SetCapture,
тогда сообщение WM_MOUSEMOVE будет приходить в это окно независимо от того,
в пределах окна находится курсор или нет

это будет продолжаться, пока не будет вызван ReleaseCapture,
либо кто-то другой не перехватил инициативу (пришел WM_CAPTURECHANGED)
вызвать ReleaseCapture нужно в момент, когда объект сброшен, т.е. левая кнопка мыши отпущена
подробные примеры использования этих функций можно найти, используя поиск на форуме

2. "отрисовка объекта"
не совсем корректная модель отрисовки перемещаемого объекта:
как я понимаю, он отрисовывается не на WM_PAINT, а на WM_MOUSEMOVE

на WM_MOUSEMOVE ничего рисовать не надо, достаточно подать команду на перерисовку (InvalidateRect/Rgn)
а отрисовывать движение в WM_PAINT (у тебя уже есть флаг состояния Mode, вот его и тестируй в WM_PAINT)

3. "перемещение объекта"
можно использовать 3 способа перемещения объекта:

- перемещение самого объекта, когда на WM_MOUSEMOVE меняются его координаты

- перемещение дубля (временного объекта), когда создается копия объекта и перемещается вслед за мышкой,
а установка координат оригинала производится в момент его сброса на окно,
тут же производится уничтожение дубля

- перемещение смещения: когда при перемещении мыши, фиксируется смещение объекта,
на которое он должен быть сдвинут. но сам объект не затрагивается до момента сброса,
а на WM_PAINT, производится рисование этой мнимой копии объекта

первый и третий варианты наиболее корректные
их плюсы и минусы зависят только от скорости отрисовки сложных объектов
это уже вопрос оптимизации и GUI

4. "единое начало координат"
рисование в двух окнах одновременно требует установки единого измерения, в которых отрисовываются все объекты
т.е., к примеру: задать для объектов начало координат в левой верхней точке большого окна,
и повесить соответствующие процедуры отрисовки объектов в эти окна,
которые будут пересчитывать эти виртуальные координаты на свою клиентскую область
после этого, уже не важно будет, через какое окно объект протягивается,
рисоваться он будет одинаково в обоих

5. "форточки"
еще один вариант отрисовки в нескольких окнах - это когда на единое пространство, в котором живут все объекты можно посмотреть из разных "форточек", т.е. когда мы сами задаем положение "форточки", через которую смотрим на объекты (можно даже скроллить)
для этого, каждому окну нужно задать пару [x,y], которая определяет положение левого верхнего угла нашей "форточки" в координатах пространства объектов, тогда координаты любого объекта в данной "форточке" можно получить вычитая эту пару из его координат

6. "самое простое"
не использовать единого пространства,
не привязываться к единому хранилищу объектов,
а просто фиксировать момент сброса объекта на главном окне,
в который и создавать его заново (или копировать/перемещать из маленького окна),

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

::ClientToScreen( hwndSmall, &point );
::ScreenToClient( hwndLarge, &point );

а Invalidate... вызывать для обоих окон

7. "самый кривой"
рисовать объект на нулевом девайсе, используя двойной XOR,
при этом объект при перемещении будет виден как в этих двух окнах,
так и в любом другом окне (имитация некоторого подобия курсора в виде объекта)

ps:
пункты 1,2,3 - обязательны
пункт 4 - частный случай пункта 5
пункт 6 - рекомендую
пункт 7 - спорный, но актуальный, по прежнему


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
namervasek
Дата 21.7.2009, 17:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 3.12.2007

Репутация: нет
Всего: нет



GremlinProg, 

Спасибо большо помогло smile 
PM MAIL   Вверх
namervasek
Дата 23.7.2009, 16:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 3.12.2007

Репутация: нет
Всего: нет



Эх погаричился я закрывать тему((
Все вроде бы работало пока не нашел в проге ошибку. 
Вот собствено она
Код

case WM_PAINT:
{
    OnPaint(hwnd); 
    UpdateWindow(hwnd_image);
    UpdateWindow(hwnd_but2);
    UpdateWindow(hwnd_MImage);         
}


После недолгих эксперементов понял что так делать нелязя.
Ошибку исправил но теперь опять фигура рисуется не так как надо((((
Если точнее фигура рисуется, но рисутеся она нормально только на главном окне. 
Вот код событий этого окна
Код

void OnMouseMove(HWND hwnd, int x,int y, WPARAM wparam)
{    

      if (wparam & MK_LBUTTON)
      {
      int i;  
      for (i = 0; i <=p_massize-1; i++)
      {
          p_mas1[i].x=p_mas1[i].x+(x-old_point_a.x);
          p_mas1[i].y=p_mas1[i].y+(y-old_point_a.y);
      }          
      old_point_a.x=x;
      old_point_a.y=y;
      InvalidateRgn(hwnd,NULL,true);      
              UpdateWindow(hwnd);
    }

}

void OnPaint(HWND hwnd)
{
  int i=0;
  PAINTSTRUCT ps;
  HBRUSH br;
  HDC hdc = BeginPaint(hwnd,&ps); 
  

  if (p_mas1!=NULL && Mode==2) 
  {       
       for (i = 0; i <=p_massize-2; i++)
       {
          MoveToEx(hdc,p_mas1[i].x, p_mas1[i].y, (LPPOINT) NULL);
          LineTo(hdc,p_mas1[i+1].x, p_mas1[i+1].y);

       }
       MoveToEx(hdc,p_mas1[i].x, p_mas1[i].y, (LPPOINT) NULL);
       LineTo(hdc,p_mas1[0].x, p_mas1[0].y);       
  }  

  EndPaint(hwnd,&ps);

}



Тоесть фигура рисуется но если какая то часть это фигуры находится внутри области какого либо дочернего окона то эта часть  сразу закрывается этим окном  Как показал метод "тыка"  фигура рисуется там где и надо но после того как обработчик WM_PAINT главного окна завершается происходит перерисовка всех дочерних окон и таким оразом они закрывают собой часть фигуры.
user posted image

Пытался сделать так:
Код

void OnMouseMove(HWND hwnd, int x,int y, WPARAM wparam)
{    

    if (wparam & MK_LBUTTON)
    {
      int i;  
              BufRegion=CreatePolygonRgn(p_mas1,p_massize,WINDING);         
      
      for (i = 0; i <=p_massize-1; i++)
      {
          p_mas1[i].x=p_mas1[i].x+(x-old_point_a.x);
          p_mas1[i].y=p_mas1[i].y+(y-old_point_a.y);
      }          
      old_point_a.x=x;
      old_point_a.y=y; 

      InvalidateRgn(hwnd,BufRegion,true);
      UpdateWindow(hwnd);
    }
}
  
По логике функция должна работать так: 
1) Запомнить старую позию фигуры
2)посчитал новые координаты
3)спомощью InvalidateRgn-та затереть старую фигу по старой позиции и потом нарисовать новую с помощью OnPaint-a

Но опять же дочерние окна перекрывают фигуру.... и в добавок функция не стирает старый рисунок.
user posted image

Из этого вытикает вопрос: как же нормально рисвоать эту фигуру?????????
Полный код снизу:


Присоединённый файл ( Кол-во скачиваний: 3 )
Присоединённый файл  ggg.rar 4,01 Kb
PM MAIL   Вверх
GremlinProg
Дата 23.7.2009, 17:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(namervasek @  23.7.2009,  18:29 Найти цитируемый пост)
как же нормально рисвоать эту фигуру?

Цитата(GremlinProg @  21.7.2009,  16:04 Найти цитируемый пост)
рисовать "плавающий" объект нужно в обоих окнах (любым из трех способов)

на главном окне ее рисовать вообще не надо, если уж ты сам решил, что тебе нужно 2 окна
Цитата(namervasek @  23.7.2009,  18:29 Найти цитируемый пост)

void OnMouseMove(HWND hwnd, int x,int y, WPARAM wparam)
{    

      if (wparam & MK_LBUTTON)
      {
      int i;  
      for (i = 0; i <=p_massize-1; i++)
      {
          p_mas1[i].x=p_mas1[i].x+(x-old_point_a.x);
          p_mas1[i].y=p_mas1[i].y+(y-old_point_a.y);
      }          
      old_point_a.x=x;
      old_point_a.y=y;
      InvalidateRgn(hwnd,NULL,true);      
              UpdateWindow(hwnd);
    }

}

я конечно понимаю, что это очень большой секрет, но когда неизвестно, откуда берется A, то совсем не важно, как ее использует B, т.к. вероятность того, что код, где может содержаться ошибка ты так и не показал, близка к 100%

хорошо, давай сделаем так:

1. координаты фигуры будут всегда расчитываться относительно левого верхнего угла клиентской области главного окна
(вчитайся в выделенный текст, каждое слово имеет смысл)

2. ставишь обработчик WM_PAINT на большое дочернее окно так:
Код

std::vector<POINT> points;
for(i = mass.size(); i-- ;){
  points.assign( mass[i].begin(), mass[i].end() );
  ::MapWindowPoints( hwndFrame, hwndLarge, &points[0], points.size() );
  ::Polyline( hdc, &points[0], points.size() );
}


3. ставишь обработчик WM_PAINT на маленькое дочернее окно так:
Код

std::vector<POINT> points;
for(i = mass.size(); i-- ;){
  points.assign( mass[i].begin(), mass[i].end() );
  ::MapWindowPoints( hwndFrame, hwndSmall, &points[0], points.size() );
  ::Polyline( hdc, &points[0], points.size() );
}


4. процедура создания фигуры в маленьком окне, т.е. добавление очередной точки в массив точек фигуры (подразумевается, что это происходит на событие WM_LBUTTONDOWN):
Код

POINT pt;
pt.x = x;
pt.y = y;
::MapWindowPoints( hwndSmall, hwndFrame, &point, 1 );
mass[index_of_new_figure].push_back( point );


5. процедура захвата объекта из маленького окна, перед перемещением (подразумевается, что это происходит на событие WM_LBUTTONDOWN) (для большого - по аналогии):
Код

POINT pt;
pt.x = x;
pt.y = y;
::MapWindowPoints( hwndSmall, hwndFrame, &point, 1 );
for(captured_figure_index = -1, i = mass.size();i--;){
  if( pt_in_figure( pt, mass[i] ) ){
    captured_figure_index = i;
    fix_point    = min_xy_of_figure( mass[i] );
    fix_point.x = pt.x - fix_point.x;
    fix_point.y = pt.y - fix_point.y;
    break;
  }
}


6. процедура перемещения объекта по маленькому окну (подразумевается, что это происходит на событие WM_MOUSEMOVE) (для большого - по аналогии):
Код

POINT pt;
pt.x = x;
pt.y = y;
::MapWindowPoints( hwndSmall, hwndFrame, &point, 1 );
if( captured_figure_index != -1 ){
  zero_point    = min_xy_of_figure( mass[captured_figure_index] );
  for(i = mass[captured_figure_index].size();i--;){
    POINT&m = mass[captured_figure_index][i];
    m.x = pt.x - fixed_point.x + ( m.x - zero_point.x );
    m.y = pt.y - fixed_point.y + ( m.y - zero_point.y );
  }
}


вот и все

в примерах я использовал stl-контейнеры для наглядности и первый способ перемещения:
Цитата(GremlinProg @  21.7.2009,  16:04 Найти цитируемый пост)
- перемещение самого объекта, когда на WM_MOUSEMOVE меняются его координаты


hwndSmall - дескриптор маленького окна
hwndLarge - дескриптор большого окна
hwndFrame - дескриптор главного окна
mass - массив фигур
index_of_new_figure - индекс фигуры в массиве mass, которая создается в данный момент
captured_figure_index - индекс фигуры в массиве mass, которая "захвачена" и в данный момент переносится
pt_in_figure - простой метод определения находится ли данная точка в пределах фигуры
min_xy_of_figure - простой метод нахождения левого-верхнего угла фигуры (найти среди всех координат минимальные)
fix_point - глобальная точка, хранящая смещение {x,y} относительно левого-верхнего угла фигуры (в этой точке находится курсор мыши над фигурой, относительно нее и расчитываются новые координаты)

вроде бы ничего не забыл

когда заставишь свой код "работать", можно будет уже отвязаться от левого верхнего угла клиентской области главного окна
для этого достаточно будет провести рефакторинг по всем участкам кода, содержащим MapWindowPoints
и выделить собственные методы преобразования координат,
очевидно, здесь требуются только 4 вида таких преобразований:

small_to_mass()
large_to_mass()
mass_to_small()
mass_to_large()

подумай, чем их наполнить,
в крайнем случае, привязка к главному окну ничего страшного не несет

Добавлено через 14 минут и 14 секунд
так, перемешал я тут местами переменные:
pt и point - это одно и то же
код "с коленок", так что смотри суть


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
namervasek
Дата 23.7.2009, 20:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 3.12.2007

Репутация: нет
Всего: нет



Эм.. такс..
Цитата

на главном окне ее рисовать вообще не надо, если уж ты сам решил, что тебе нужно 2 окна

А как же тогда?  smile
Может я неправльно раньше просто обьяснил- Мне нужно перетащить фигуру из маленького окна в большое, причем чтобы когда я перетаскивал фигура двигалась за курсором по все области главного окна. 
 
Код который ты привел  на stl, я на нем не песал поэтому могу ошибиться но как я понял ты привел мне пример расчета координат и  отрисовки самих фигур внутри дочерних окон. А это как раз я зделал и все координаты у меня расчитываются правильно как мне и надо у меня не правильно рисуется образ перетасивоемой фигуры. Образ рисуется неправильно не изза плохих координат а изза некоректной отрисовки. 
На случай если не правильно понял...
Вот как я сделал:




hwnd_form-главное окно
hwnd_image-маленькое
hwnd_MImage-большое
p_mas-это указатель на динам масив в котором хранятся точки фигуры расположеной в мелком окне
p_mas1-это тоже указатель только он служит для координат передвигаемого образа
p_massize-это размера обоих масивов
old_point_a-эм.....  это как я понял тоже самое что у тебя fix_point
Mode- режим 1=фигура в маленьком окне не нарисовна 2-фигура перетаскивается(точнее её образ)
3= фигура в маленьком окне нарисована(я подрузомиваю под этим что она замкнута)

1. Процедура занесения точек фигуры в масив (то что красным выделено не относится к формированию фигуры)
Код


void Image_OnMouseDown(HWND hwnd, int x,int y)
{
  static POINT point_b={-1,-1};  
  int i;
  if (Mode==1)
  {
    if (p_mas==NULL)  //если фигуры или начальной точки фигуры нет 
    { 
      p_massize++;
      p_mas=(POINT*)malloc(sizeof(POINT));
      p_mas[0].x=x;
      p_mas[0].y=y;      
    }
    else 
    {
      if (x>=(p_mas[0].x-4) && x<=(p_mas[0].x+4) && y>=(p_mas[0].y-4) && y<=(p_mas[0].y+4)) // если клик пришелся на область вокрук начальной точки фигуры то фигура считается замкнутой и нарисовнай
      {
          Mode=EndPaintMode;
          Region=CreatePolygonRgn(p_mas,p_massize,WINDING);
          InvalidateRect(hwnd,NULL,true);
          UpdateWindow(hwnd);
      }
      else // если нет то просто добавлем еще одну точку
      {
          p_massize++;
          p_mas=(POINT *) realloc(p_mas,sizeof(POINT)*p_massize);
                  p_mas[p_massize-1].x=x;
          p_mas[p_massize-1].y=y;

      }  
    }
  }
[color=red]  
if (Mode==3) // здесь проверяется был ли клик на построеной фигуре  если да то соотвествено создается образ фигуры и как ты посоветовал производится захват путем SetCapture
  { 
     if (PtInRegion(Region,x,y)) 
     {
         Mode=MoveMode;
         SetCapture(hwnd_form); //         
         old_point_a.x=x+530; // вот так я преобразую координаты(530 и 10 это позиция маленького окна)
         old_point_a.y=y+10;
         p_mas1=(POINT*)malloc(sizeof(POINT)*p_massize);
         for (i = 0; i <=p_massize-1; i++)
         {
            p_mas1[i].x=p_mas[i].x+530;
            p_mas1[i].y=p_mas[i].y+10;
         }

     }
  }
[/color]

}



2. Процедура рисования фигуры(в смысле рисуется  фигура с нуля а не готовая )
повтарюсь здесь только рисование новой фигуры поэтому на это процедуру можно не смореть, разместил только для "ознакомления"
Код

void Image_OnMouseMove(HWND hwnd, int x,int y, WPARAM wparam)
{
  static POINT old_point_b={0,0};
  static POINT old_point_c={0,0};
  static bool f=false;  
  static bool f1=false;

  if (p_mas!=NULL && Mode==1 ) 
  {
      HDC hdc = GetDC(hwnd);      
      Ellipse(hdc,p_mas[0].x-4, p_mas[0].y-4, p_mas[0].x+4, p_mas[0].y+4);      
      SetROP2(hdc, R2_NOTXORPEN);

      if (f)
      {
          MoveToEx(hdc,p_mas[p_massize-1].x, p_mas[p_massize-1].y, (LPPOINT) NULL);
          LineTo(hdc, old_point_b.x, old_point_b.y);
      }      
      
      MoveToEx(hdc,p_mas[p_massize-1].x, p_mas[p_massize-1].y, (LPPOINT) NULL);
      LineTo(hdc, x, y); 


      f=true;
      old_point_b.x=x;
      old_point_b.y=y;
      
      ReleaseDC(hwnd, hdc);  
  }
  else
  {
      old_point_b.x=0;
      old_point_b.y=0;
      f=false;
  }
}


3. Обработчик OnPaint для маленького окна(если я правлино понял разницы тут никакой нет с твоим)
Здесь просто отрисовывается фигура по p_mas  в маленьком окне
Код

void Image_OnPaint(HWND hwnd)
{ 
  int i=0;
  PAINTSTRUCT ps;
  HDC hdc = BeginPaint(hwnd,&ps);
  
  if (p_mas!=NULL && Mode!=1) 
  {       
          for (i = 0; i <=p_massize-2; i++)
         {
          MoveToEx(hdc,p_mas[i].x, p_mas[i].y, (LPPOINT) NULL);
          LineTo(hdc,p_mas[i+1].x, p_mas[i+1].y);
          }
       MoveToEx(hdc,p_mas[i].x, p_mas[i].y, (LPPOINT) NULL);
       LineTo(hdc,p_mas[0].x, p_mas[0].y);       
  }  
  EndPaint(hwnd,&ps);
}


Дальше у меня идут процедуры главного окна так там я делаю перасчет образа фигу и отрисовываю там.

4. Движенье мыщью на главном окне(сдесь только перерасчет и вызоов WM_PAINT)
Код

 void OnMouseMove(HWND hwnd, int x,int y, WPARAM wparam)
{ 
    if (wparam & MK_LBUTTON)
    {
      int i;  
             BufRegion=CreatePolygonRgn(p_mas1,p_massize,WINDING);      
    
      
      for (i = 0; i <=p_massize-1; i++) // сообствено сам перерасчет
      {
          p_mas1[i].x=p_mas1[i].x+(x-old_point_a.x);
          p_mas1[i].y=p_mas1[i].y+(y-old_point_a.y);
      }          
      old_point_a.x=x;
      old_point_a.y=y; 

[color=red]      
     InvalidateRgn(hwnd,NULL,true);  // вот примерно здесь я  считаю где то моя ощибка так после этих строк и вызывается перисовка всех окон
      UpdateWindow(hwnd);
[/color]
    }
    else
    {
    }
}


5. Обработчик OnPaint для главного окна
Здесь делается тоже самое что и в OnPaint мелкого окна с той лишь разницей что здесь отрисовывается образ той фигуры котороя находится в мелком окне.  
Код

void OnPaint(HWND hwnd)
{
  int i=0;
  PAINTSTRUCT ps;
  HBRUSH br;
  HDC hdc = BeginPaint(hwnd,&ps); 

  if (p_mas1!=NULL && Mode==2) 
  {       
         for (i = 0; i <=p_massize-2; i++)
       {
          MoveToEx(hdc,p_mas1[i].x, p_mas1[i].y, (LPPOINT) NULL);
          LineTo(hdc,p_mas1[i+1].x, p_mas1[i+1].y);

       }
       MoveToEx(hdc,p_mas1[i].x, p_mas1[i].y, (LPPOINT) NULL);
       LineTo(hdc,p_mas1[0].x, p_mas1[0].y);      
  }  
  EndPaint(hwnd,&ps);
}



Есть еще OnMouseUp для главного окна но там ни чего не пересчитвается и не рисуется только уничтожается  p_mas1  а его содиржимое переход в линейный список содержащий все фигуры расположены на большом окне после этого вызывается перерисовка главного окна.

Из тех пунктов в  которых ты описывал общие понятия перетаскивания раньше
я выполнил 1.2.3.4 


Это сообщение отредактировал(а) namervasek - 23.7.2009, 20:57
PM MAIL   Вверх
GremlinProg
Дата 23.7.2009, 22:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(namervasek @  23.7.2009,  22:50 Найти цитируемый пост)
Может я неправльно раньше просто обьяснил- Мне нужно перетащить фигуру из маленького окна в большое

я тебе просто показывал вариант жизни объектов на одной плоскости за двумя окнами:
представь, ты находишься в доме с 2-мя окнами, и смотришь через них как по улице движется машина
сначала ты увидишь ее в одном окне, потом - в другом

ты же не сказал, что тебя интересует подобие варианта №7,
поэтому я выбрал сам
Цитата(namervasek @  23.7.2009,  22:50 Найти цитируемый пост)
Код который ты привел  на stl, я на нем не песал поэтому могу ошибиться

очень жаль, поскольку, как ты сам скорее всего заметил,
очень мало людей рвутся расковыривать велосипеды, в поисках той самой причины, по которой ты к нам заглянул,
нужно понимать, что от наглядности кода зависит результат, на который ты расчитываешь

Цитата(namervasek @  23.7.2009,  22:50 Найти цитируемый пост)

Образ рисуется неправильно не изза плохих координат а изза некоректной отрисовки

Цитата(namervasek @  23.7.2009,  22:50 Найти цитируемый пост)

p_mas1[i].x=p_mas1[i].x+(x-old_point_a.x);
p_mas1[i].y=p_mas1[i].y+(y-old_point_a.y);

подумай еще раз, что ты тут делаешь,
допустим, x - old_point_a.x - это смещение
на каждое движение движение мыши, к примеру вправо, это смещение будет постоянно расти,
а ты его еще суммируешь с текущей координатой фигуры,
что выходит:
переместившись вправо на 1 пиксел, фигура переместится вправо на 1 пиксел,
далее, переместившись вправо еще на 1 пиксел, фигура переместится вправо уже на 2 пиксела и т.д.

а теперь скажи мне, при чем тут прорисовка?
почему ты так настаиваешь на проблемах именно при рисовании?
ведь координаты пересчитываются неправильно

как правильно, я уже показал
в данном случае нельзя при расчете координат повторно использовать координаты от предыдущего шага,
найди константу в фигуре и опирайся на нее (у меня эта константа - расстояние каждой точки до левого верхнего угла фигуры)

в любом случае, для перемещения между окнами, ни как не взаимодействующих между собой, я бы ни в коем случае не использовал XOR-технику, т.к. любое внешнее вмешательство будет являться источником нежелательных артефактов
xor удобно для временного решения

логичнее было бы создание прозрачного плавающего окна - переносчика объектов с эффектом HTTRANSPARENT


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
namervasek
Дата 24.7.2009, 17:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 3.12.2007

Репутация: нет
Всего: нет



БОЖЕ КАКОЙ Я ИДИОТ smile  smile 
Вот как надо было сделать(сразу говорю код сырой доделывать буду)
Код


void OnMouseMove(HWND hwnd, int x,int y, WPARAM wparam)
{    

    if (wparam & MK_LBUTTON)
    {
      int i;  
      InvalidateRgn(hwnd,NULL,true);
      UpdateWindow(hwnd);
      for (i = 0; i <=p_massize-1; i++)
      {
          p_mas1[i].x=p_mas1[i].x+(x-old_point_a.x);
          p_mas1[i].y=p_mas1[i].y+(y-old_point_a.y);
      }          
      old_point_a.x=x;
      old_point_a.y=y; 
      HDC hdc = GetDC(hwnd);  
      if (p_mas1!=NULL && Mode==2) 
      {       
          for (i = 0; i <=p_massize-2; i++)
         {
                     MoveToEx(hdc,p_mas1[i].x, p_mas1[i].y, (LPPOINT) NULL);
                     LineTo(hdc,p_mas1[i+1].x, p_mas1[i+1].y);
         }
               MoveToEx(hdc,p_mas1[i].x, p_mas1[i].y, (LPPOINT) NULL);
               LineTo(hdc,p_mas1[0].x, p_mas1[0].y);      
      }
      ReleaseDC(hwnd, hdc);
    }
}

void OnPaint(HWND hwnd)
{
  int i=0;
  PAINTSTRUCT ps;  
  HDC hdc = BeginPaint(hwnd,&ps); 
  EndPaint(hwnd,&ps);
}


Тоесть достаточно было просто в Move очистить экран и внем же рисовать smile 


Цитата

подумай еще раз, что ты тут делаешь,
допустим, x - old_point_a.x - это смещение
на каждое движение движение мыши, к примеру вправо, это смещение будет постоянно расти,
а ты его еще суммируешь с текущей координатой фигуры,
что выходит:
переместившись вправо на 1 пиксел, фигура переместится вправо на 1 пиксел,
далее, переместившись вправо еще на 1 пиксел, фигура переместится вправо уже на 2 пиксела и т.д.

Так я же вот так потом делаю
      old_point_a.x=x;
      old_point_a.y=y;
Тоесть как ты и говорил я сделал эту точку "начала" но она просто у меня меняется. Согласен что у меня кривовато все сделано но это только пока так smile  потом я это доработаю естествено.
Еше раз спс за помощь smile 
Если интересно код с исходником прикрепил к посту.

Присоединённый файл ( Кол-во скачиваний: 6 )
Присоединённый файл  ggg.rar 30,92 Kb
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0659 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.