Форум программистов
Правила форума  |  Исходники Delphi  |  Основы Delphi  |  Блог программистов  |  Рассылка  |  Конкурс программистов!


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

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

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

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

Цитата:
Сообщение от 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, 21:10   #4
rpy3uH
воин дзена
СуперМодератор
 
Аватар для rpy3uH
 
Регистрация: 29.10.2006
Адрес: Где-то рядом....
Сообщений: 2,528
Репутация: 1041
По умолчанию

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

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

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

Последний раз редактировалось unnamed; 14.06.2007 в 15:12.
unnamed вне форума   Ответить с цитированием
Старый 14.06.2007, 15:11   #7
unnamed
Пользователь
 
Регистрация: 08.04.2007
Сообщений: 16
Репутация: 72
По умолчанию

Цитата:
Сообщение от 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;
}

unnamed вне форума   Ответить с цитированием
Старый 14.06.2007, 15:58   #8
unnamed
Пользователь
 
Регистрация: 08.04.2007
Сообщений: 16
Репутация: 72
По умолчанию

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

Код:

#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, 19:33   #9
JTG
я получил эту роль
Заслуженный модератор
 
Аватар для JTG
 
Регистрация: 25.05.2007
Адрес: тут темно и с потолка капает
Сообщений: 2,821
Репутация: 1633
Отправить сообщение для JTG с помощью ICQ
По умолчанию

Респект Безымянному =)
//Правда не проверял
__________________
моё бгло
JTG вне форума   Ответить с цитированием
Ответ

Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

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


06:47.


Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.

Создание и продвижение сайтов - "Веб сателлит"    Ссылки

seocraft.ru bsc