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

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

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

Восстановить пароль

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

Ответ
 
Опции темы Поиск в этой теме
Старый 08.06.2007, 21:30   #1
ShiSha_34
Новичок
Джуниор
 
Регистрация: 08.06.2007
Сообщений: 1
По умолчанию Drag n Drop объект в чужом окне

Подскажите пожалуйста, как сделать так, чтобы в любом окне можно было создать Drag&Drop объект, который будет являться копией объекта из моей программы.. Т.е. предположим в моей программе есть квадратик, который можно перемещать, мне надо создать его копию в любом окне, в котором он также сможет перемещаться и после сворачивания/разворачивания чужого окна его координаты оставались бы прежними.. Зараниее спасибо =)
ShiSha_34 вне форума Ответить с цитированием
Старый 09.06.2007, 07:55   #2
rpy3uH
добрый няша
Старожил
 
Аватар для rpy3uH
 
Регистрация: 29.10.2006
Сообщений: 4,804
По умолчанию

в чужом окне нельзя создать какой-либо объект.
rpy3uH вне форума Ответить с цитированием
Старый 10.06.2007, 12:18   #3
unnamed
Пользователь
 
Регистрация: 08.04.2007
Сообщений: 15
По умолчанию

Цитата:
Сообщение от rpy3uH Посмотреть сообщение
в чужом окне нельзя создать какой-либо объект.
Вы меня удивляете. Имея хэндл чужого окна, можно сделать с ним всё тоже, что и с собственным. Всё, что нужно - это: 1) Написать функцию (обработчик событий) вида LRESULT CALLBACK WindowProc(HWND,UINT,WPARAM,LPARAM) в которой реализуйте Drag n Drop - это достаточно просто. Для этого нужно будет обработать всего два события - WM_LBUTTONDOWN и WM_LBUTTONUP. При реализации этого используйте функцию SetCapture, чтобы при выходе курсора за границы окна во время перетаскивания, перетаскиваемый объект не "падал". В своё время я с этим намучился. 2) Зарегестрируйте свой класс (RegisterWindowClassEx) - в вашем примере, ShiSha_34, это будет чёрное окно без рамки. В качестве соответсвующего параметра (я имею ввиду поле lpfnWndProc структуры WNDCLASSEX) ф-ии RegisterWindowClassEx укажите написанный вами обработчик событий. 3) Получите хэнл окна, в котором вы хотите создать свой чёрный квадрат. Это можно сделать, например, заная имя и (или) класс чужого окна при помощи ф-ии FindWindow. Или же поставить ловушку (SetWindowHook), которая будет срабатывать при клике мышкой на выбраном окне. Метод не важен и здесь о них писали предостаточно. Получив хэндл чужого окна, создайте свой объект при помощи ф-ии CreateWindowEx, в которой в качестве класса укажите зарегестрированный вами клас (пункт 2), а в качестве хэндла родительского окна - полученный хэндл. В результате должно получиться то, что вы описали в вопросе. Для получения более подробно информации воспользуйтесь WIN32 Programmer's Reference.
Практика - лучший критерий истины. К.Маркс.
unnamed вне форума Ответить с цитированием
Старый 12.06.2007, 20:10   #4
rpy3uH
добрый няша
Старожил
 
Аватар для rpy3uH
 
Регистрация: 29.10.2006
Сообщений: 4,804
По умолчанию

я сомневаюсь......
при создании чего либо на чужом окне и при каких либо действиях с ним сообщение будет посылаться форме чужого приложения, и обрабатывать его будет процедура которую зарегистрировала чужая программа
--------------------------
ладно, допустим ты прав
приведи пример: сделай два приложения, одно приложение с одной пустой формой, и второе которое будет осуществлять всё приведённые тобою действия
rpy3uH вне форума Ответить с цитированием
Старый 12.06.2007, 21:24   #5
Сильванович Михаил
Студент
Форумчанин
 
Регистрация: 10.11.2006
Сообщений: 196
По умолчанию

To Unnamed:
Цитата:
Сообщение от rpy3uH Посмотреть сообщение
ладно, допустим ты прав
приведи пример: сделай два приложения, одно приложение с одной пустой формой, и второе которое будет осуществлять всё приведённые тобою действия
Да пожалуйста выложи кодик, или оставь кусками в посте - очень
интересная тема.
Visita Interiorem Terrae Rectificando Operae Lapidem...
Сильванович Михаил вне форума Ответить с цитированием
Старый 14.06.2007, 14:09   #6
unnamed
Пользователь
 
Регистрация: 08.04.2007
Сообщений: 15
По умолчанию

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

Цитата:
Сообщение от rpy3uH Посмотреть сообщение
ладно, допустим ты прав
приведи пример: сделай два приложения, одно приложение с одной пустой формой, и второе которое будет осуществлять всё приведённые тобою действия
Пацан сказал - пацан сделал
Вот код первого приложения (пустая форма). Это можно не читать, важно только то, что класс окна и его имя - SIMPLE_WINDOW. Код сгенерирован автоматически средой Code::Blocks.

Код:
#include <windows.h>

/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/*  Make the class name into a global variable  */
char szClassName[ ] = "SIMPLE_WINDOW";

int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nFunsterStil)
{
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default color as the background of the window */
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;

    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           "SIMPLE_WINDOW",       /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           544,                 /* The programs width */
           375,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );

    /* Make the window visible on the screen */
    ShowWindow (hwnd, nFunsterStil);

    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }

    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}


/*  This function is called by the Windows function DispatchMessage()  */

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)                  /* handle the messages */
    {
        case WM_DESTROY:
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
            break;
        default:                      /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}
Практика - лучший критерий истины. К.Маркс.

Последний раз редактировалось Stilet; 09.11.2010 в 09:42.
unnamed вне форума Ответить с цитированием
Старый 14.06.2007, 14:58   #7
unnamed
Пользователь
 
Регистрация: 08.04.2007
Сообщений: 15
По умолчанию

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

Код:
#include <windows.h>

/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/*  Make the class name into a global variable  */
char szClassName[ ] = "BLACK_SQUARE";
HWND Target;

int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nFunsterStil)
{
    HWND hwnd;
    MSG messages;
    WNDCLASSEX wincl;

    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;
    wincl.style = CS_DBLCLKS;
    wincl.cbSize = sizeof (WNDCLASSEX);
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;
    wincl.cbClsExtra = 0;
    wincl.cbWndExtra = 0;
    wincl.hbrBackground = (HBRUSH)(COLOR_BACKGROUND+1); 
//СОЗДАВАЕМОЕ ОКНО ДОЛЖНО ХОТЬ ЧУТЬ-ЧУТЬ ОТЛИЧАТСЯ ЦВЕТОМ ОТ РОДИТЕЛЬСКОГО:)

    if (!RegisterClassEx (&wincl)) return 0;


    //ДО ЭТОГО МОМЕНТА ВЕСЬ КОД АНАЛОГИЧЕН ПРЕДЫДУЩЕМУ.
    //А ТЕПЕРЬ - ВКУСНЕНЬКОЕ

    Target=FindWindow("SIMPLE_WINDOW","SIMPLE_WINDOW");
    if (!Target)
    {
      MessageBox(0,"Запустите приложение SIMPLE_WINDOW","!! ERROR",MB_OK);
      return 0;
    }
    hwnd = CreateWindowEx (
           0,
           szClassName,
           "BLACK_SQUARE",
           WS_CHILD,  //НАШЕ ОКНО БУДЕТ ДОЧЕРНИМ ДЛЯ SIMPLE_WINDOW
           100,
           100,
           150,
           150,
           Target,    //РОДИТЕЛЬСКОЕ ОКНО
           NULL,
           hThisInstance,
           NULL
           );
    if (!hwnd)
    {
      MessageBox(0,"WINDOWSMUSTDIE","!! ERROR",MB_OK);
      return 0;
    }
    ShowWindow(hwnd,SW_SHOW);

    while (GetMessage (&messages, NULL, 0, 0))
    {
        TranslateMessage(&messages);
        DispatchMessage(&messages);
    }
    return messages.wParam;
}

//А ВОТ СОБСТВЕННО DRAG n DROP

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  static bool lb_drag_now=false;
  static POINT cursor_pos;

    switch (message)
    {
        case WM_DESTROY:
          PostQuitMessage (0);
          break;

        case WM_LBUTTONDOWN:
          lb_drag_now=true;
          GetCursorPos(&cursor_pos); 
//НЕ СОВЕТУЮ ВМЕСТО ЭТОГО ИСПОЛЬЗОВАТЬ lParam, Т.К. ОН СОДЕРЖИТ ОТНОСИТЕЛЬНЫЕ КООРДИНАТЫ
          SetCapture(hwnd);
          break;

        case WM_LBUTTONUP:
          lb_drag_now=false;
          ReleaseCapture();
          break;

        case WM_MOUSEMOVE:
          if (lb_drag_now)
          {
            POINT current_pos;
            RECT  wnd_rect,parent_rect;

            GetCursorPos(&current_pos);
            GetWindowRect(hwnd,&wnd_rect);
            GetWindowRect(Target,&parent_rect);

            wnd_rect.left+=current_pos.x-cursor_pos.x-parent_rect.left;
            wnd_rect.top+=current_pos.y-cursor_pos.y-parent_rect.top;

            SetWindowPos(hwnd,HWND_TOP,wnd_rect.left-4,wnd_rect.top-23,0,0,SWP_NOSIZE);
            cursor_pos=current_pos;
          }
          break;

        default:
            return DefWindowProc (hwnd, message, wParam, lParam);
    }
    return 0;
}
Практика - лучший критерий истины. К.Маркс.
unnamed вне форума Ответить с цитированием
Старый 14.06.2007, 18:33   #8
JTG
я получил эту роль
Старожил
 
Аватар для JTG
 
Регистрация: 25.05.2007
Сообщений: 3,694
По умолчанию

Респект Безымянному =)
//Правда не проверял
пыщь
JTG вне форума Ответить с цитированием
Старый 09.11.2010, 02:19   #9
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,357
По умолчанию

Прикольная программа, правда у меня в Win 7 в ней разные глюки.
То квадрат есть, то нет.
При перетаскивании за границы формы и обратно квадрат покрывается непонятными полосками(
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
drag $ drop в DBGrid AlexandrSid Общие вопросы Delphi 13 21.06.2010 10:55
Помогите с drag-and-drop Cezar Win Api 3 19.10.2008 15:48
Drag&Drop в ListBox'ах MAKEDON Общие вопросы Delphi 3 21.08.2008 13:12
Drag&Drop shtuceron Общие вопросы Delphi 3 09.04.2008 19:04
Drag and Drop Xardas Общие вопросы Delphi 8 20.01.2008 23:09