Uchwyt do przeciÄ…ganego okna

dział ogólny

Uchwyt do przeciÄ…ganego okna

Nowy postprzez beherit » sobota, 25 kwietnia 2009, 12:21

Mam pewien problem. Chciałbym zdobyć jakoś uchwyt do przeciąganego okna (gdy złamiemy je i poruszamy po ekranie), żeby zdobyć jego aktualną pozycję na ekranie. Chodzi o te obramowanie na screenie:

Obrazek
Obrazek
Avatar użytkownika
beherit
Homos antropiczny
Homos antropiczny
 
Posty: 62
Dołączył(a): poniedziałek, 16 lutego 2009, 19:55
Lokalizacja: Jarocin
PodziÄ™kowaÅ‚ : 2
OtrzymaÅ‚ podziÄ™kowaÅ„: 0
System operacyjny: Windows 10
Kompilator: C++Builder XE5
Gadu Gadu: 0
    NieznanyNieznana

Re: Uchwyt do przeciÄ…ganego okna

Nowy postprzez Cyfrowy Baron » sobota, 25 kwietnia 2009, 14:57

Jaśniej proszę, gdyż chyba nie zrozumiałem.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
PodziÄ™kowaÅ‚ : 12
OtrzymaÅ‚ podziÄ™kowaÅ„: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: Uchwyt do przeciÄ…ganego okna

Nowy postprzez Cyfrowy Baron » niedziela, 26 kwietnia 2009, 09:32

No dobrze... Po chwili zastanowienia, chyba wiem o co pytasz.

W tym celu można posłużyć się komponentem TTimer, ale to by tylko niepotrzebnie wszystko skomplikowało, dlatego lepiej skorzystać z mapy komunikatów, a jeszcze lepiej i prościej jest wykorzystać funkcje WindowProc w którą jest wyposażone każde okno i większość obiektów.
Do pobrania pozycji okna na pulpicie posłuży funkcja GetCursorPos pobierająca położenie wskaźnika myszy na formularzu:


// w pliku nagłówkowym np. Unit2.h
Kod: Zaznacz cały
private:
        TWndMethod scMove;
        void __fastcall OnFormMove(TMessage& Msg);


// w pliku źródłowym np. Unit2.cpp
Kod: Zaznacz cały
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit2.h"
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm2 *Form2;
//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
    : TForm(Owner)
{
scMove = this->WindowProc;
this->WindowProc = OnFormMove;
}
//---------------------------------------------------------------------------
void __fastcall TForm2::OnFormMove(TMessage &Msg)
{
if(Msg.Msg == WM_MOVING)
{
  POINT pWindow;
  GetCursorPos(&pWindow);

  Form1->Caption = (String)pWindow.x + "  <>  " + (String)pWindow.y;
}
scMove(Msg);
}
//---------------------------------------------------------------------------


    Problemem pozostaje jednak fakt iż tak naprawdÄ™ pobierana jest pozycja kursora myszy wzglÄ™dem krawÄ™dzi ekranu, a nie pozycja okna. Można to oczywiÅ›ci odpowiednio przeliczyć, trzeba jednak pamiÄ™tać, że kursor może uchwycić okno w dowolnym miejscu paska tytuÅ‚owego. Pozycja okna wzglÄ™dem ekranu to jest: pozycja kursora - (pozycja kursora - pozycja okna po uchwyceniem paska tytuÅ‚owego).
Wymaga to zmodyfikowania funkcji OnFormMouse poprzez dodanie jeszcze jednego komunikatu:


Kod: Zaznacz cały
//---------------------------------------------------------------------------
int pX, pY;            // koniecznie zmienne globalne, można zdefiniować w pliku nagłówkowym w sekcji private

void __fastcall TForm2::OnFormMove(TMessage &Msg)
{
    POINT pWindow;

   if(Msg.WParam == HTCAPTION)
   {
      GetCursorPos(&pWindow);
      pX = (pWindow.x - this->Left);
      pY = (pWindow.y - this->Top);
   }
   if(Msg.Msg == WM_MOVING)
   {
      GetCursorPos(&pWindow);

      Form1->Caption = (String)(pWindow.x - pX) + "  <>  " + (String)(pWindow.y - pY);
   }
   scMove(Msg);
}
//---------------------------------------------------------------------------
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
PodziÄ™kowaÅ‚ : 12
OtrzymaÅ‚ podziÄ™kowaÅ„: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: Uchwyt do przeciÄ…ganego okna

Nowy postprzez beherit » niedziela, 26 kwietnia 2009, 13:04

Nie za bardzo zrozumiałeś więc napiszę to trochę inaczej. Mam otwarte okno - załóżmy, że notatnika. Uchwyt (HWND) do tego okna można pobrać bardzo prosto i potem dzięki GetWindowRect pobrać jego pozycje. Ale teraz gdy złapiemy okno poprzez górną belkę i przesuwany po ekranie to przy włączonej opcji w systemie "Pokaż zawartość okna podczas przeciągania" pojawia nam się obramowanie a przy zaznaczonej opcji wygląda jakbyśmy przeciągali na żywo te okno. Teraz chodzi mi o to, aby pobrać pozycje tego przeciąganego okna, a żeby to zrobić potrzebny mi uchwyt do niego, bo poprzez samą pozycję kursora za bardzo sobie nie poradzę...
Obrazek
Avatar użytkownika
beherit
Homos antropiczny
Homos antropiczny
 
Posty: 62
Dołączył(a): poniedziałek, 16 lutego 2009, 19:55
Lokalizacja: Jarocin
PodziÄ™kowaÅ‚ : 2
OtrzymaÅ‚ podziÄ™kowaÅ„: 0
System operacyjny: Windows 10
Kompilator: C++Builder XE5
Gadu Gadu: 0
    NieznanyNieznana

Re: Uchwyt do przeciÄ…ganego okna

Nowy postprzez Cyfrowy Baron » niedziela, 26 kwietnia 2009, 14:15

To jest dokładnie to co napisałem, ale nie możesz posłużyć się funkcją WindowProc, gdyż nie masz do niej dostępu w przesuwanym oknie, więc musisz posłużyć się obiektem TTimer w którym będzie pobierana pozycja kursora, pozycję okna można wyliczyć zgodnie z podanym przeze mnie wcześniej wzorem.
Użycie Timera stwarza jednak pewne problemu. Jak sobie przypomnę lub gdzieś znajdę informację w jaki sposób w zdarzeniu OnTimer sprawdzić stan klawiszy myszy, to podam rozwiązanie. Dodam jednak, że do określenia pozycji dowolnego okna względem krawędzi ekranu mozna posłużyć się funkcja GetWindowRect. Problemów nastręcza jednak sam Timer.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
PodziÄ™kowaÅ‚ : 12
OtrzymaÅ‚ podziÄ™kowaÅ„: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: Uchwyt do przeciÄ…ganego okna

Nowy postprzez Cyfrowy Baron » niedziela, 26 kwietnia 2009, 14:58

Właściwie to można rozwiązać problem wykorzystując haki systemowe. Nie jest to może najlepsze rozwiązanie, ale chwilowo nic innego mi nie przychodzi do głowy:
Kod: Zaznacz cały
  HHOOK g_hLogHook       = NULL;
  HWND g_hLastFocus      = NULL;

int pX, pY;
POINT pWindow;
HWND capWindow;
bool getStart = false;
String wClassName = "Notepad";
//---------------------------------------------------------------------------
HOOKPROC ConnectHook(int iCode, WPARAM wParam, LPARAM lParam)
{
if(iCode < 0) return (HOOKPROC)CallNextHookEx(g_hLogHook, iCode, wParam, lParam);

EVENTMSG *pEvt = (EVENTMSG *)lParam;
EVENTMSG *mEvt = (EVENTMSG *)wParam;

if(pEvt->message == WM_LBUTTONDOWN && pEvt->message != WM_MOUSEMOVE)
{

   capWindow = FindWindow(wClassName.c_str(), 0);

   if(capWindow > 0)
   {
    GetCursorPos(&pWindow);
    tagRECT p;
    GetWindowRect(capWindow, &p);
    pX = (pWindow.x - p.left);
    pY = (pWindow.y - p.top);
    getStart = true;
   }
}
if(pEvt->message == WM_LBUTTONUP)
{
  getStart = false;
}

if(pEvt->message == WM_MOUSEMOVE && getStart)
{
  GetCursorPos(&pWindow);
  Form1->Caption = (String)(pWindow.x - pX) + "  <>  " + (String)(pWindow.y - pY);
}

return (HOOKPROC)CallNextHookEx (g_hLogHook, iCode, wParam, lParam);
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
void __fastcall TForm1::Button7Click(TObject *Sender)
{
capWindow = FindWindow("Notepad", 0);

if(g_hLogHook == NULL)
  g_hLogHook = SetWindowsHookEx(WH_JOURNALRECORD, (HOOKPROC)ConnectHook, HInstance,0);   

}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button8Click(TObject *Sender)
{
if(g_hLogHook != NULL)
{
  UnhookWindowsHookEx(g_hLogHook);
  g_hLogHook = NULL;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
if(g_hLogHook != NULL)
{
  UnhookWindowsHookEx(g_hLogHook);
  g_hLogHook = NULL;
}
}
//---------------------------------------------------------------------------
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
PodziÄ™kowaÅ‚ : 12
OtrzymaÅ‚ podziÄ™kowaÅ„: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana


Powrót do Ogólne problemy z programowaniem

Kto przeglÄ…da forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 7 gości