Acties:
  • 0 Henk 'm!

  • Guldan
  • Registratie: Juli 2002
  • Laatst online: 20:58

Guldan

Thee-Nerd

Topicstarter
Ik ben bezig met een schrijven van een c++ applicatie die moeten weten wanneer twee windows volledig over elkaar heen staan.

Ik heb wel code om aan een HWND te komen van het window op de voorgrond en het window van mijn applicatie alleen werkt dat niet helemaal lekker:

C++:
1
2
3
4
5
6
7
8
9
HWND otherwindow;
otherwindow = GetForegroundWindow();

if(window1.hwnd == otherwindow)
{
//window1 is het foreground window
}else{
//window1 is GEEN foreground
}


Dit lijkt an sich wel goed te werken, maar wanneer deze code vaker aangeroepen wordt want dit dient regelmatig gecheckt te worden dan pakt hij soms een ander window als foreground window. (Hij pakt wanneer ik debug soms het visual studio venster terwijl deze niet actief is) Dit lijkt mij niet te kloppen. Zou iemand mij een aanwijzing kunnen geven waarom dit gedrag optreed?

You know, I used to think it was awful that life was so unfair. Then I thought, wouldn't it be much worse if life were fair, and all the terrible things that happen to us come because we actually deserve them?


Acties:
  • 0 Henk 'm!

  • leuk_he
  • Registratie: Augustus 2000
  • Laatst online: 15-07 15:35

leuk_he

1. Controleer de kabel!

getforegroundwindow bepaald wat het actieve window is wat de input heeft, niet of het overlapped met je applicatie window.

wellicht helpt WindowFromPoint of getdc (en dan pixels ophalen) je meer.

Need more data. We want your specs. Ik ben ook maar dom. anders: forum, ff reggen, ff topic maken
En als je een oplossing hebt gevonden laat het ook ujb ff in dit topic horen.


Acties:
  • 0 Henk 'm!

  • Guldan
  • Registratie: Juli 2002
  • Laatst online: 20:58

Guldan

Thee-Nerd

Topicstarter
Misschien is het niet duidelijk genoeg geweest: stel, ik heb een venster van notepad en ik wil weten of deze(niet geminimaliseerd) nog achter een ander venster staat (word). dan is het toch logisch om te checken of het foreground window anders is dan 'notepad'.

Ik zal ondertussen even naar windowfrompoint kijken.

You know, I used to think it was awful that life was so unfair. Then I thought, wouldn't it be much worse if life were fair, and all the terrible things that happen to us come because we actually deserve them?


Acties:
  • 0 Henk 'm!

  • leuk_he
  • Registratie: Augustus 2000
  • Laatst online: 15-07 15:35

leuk_he

1. Controleer de kabel!

Guldan schreef op maandag 19 januari 2009 @ 12:07:
Misschien is het niet duidelijk genoeg geweest: stel, ik heb een venster van notepad en ik wil weten of deze(niet geminimaliseerd) nog achter een ander venster staat (word). dan is het toch logisch om te checken of het foreground window anders is dan 'notepad'.
Ook andere windows dan het forgroundwindow kunnen voor je window staan.

-een windows tussen het voorgrond windows en jouw window
-popup van andere applicatie.
-een window van een "always on top applicatie"

De vraag moet eigenlijk zijn:

Waarom wil je weten of windows over elkaar heen staan.

[ Voor 7% gewijzigd door leuk_he op 19-01-2009 12:46 ]

Need more data. We want your specs. Ik ben ook maar dom. anders: forum, ff reggen, ff topic maken
En als je een oplossing hebt gevonden laat het ook ujb ff in dit topic horen.


Acties:
  • 0 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
Sowieso geeft GetForegroundWindow je een resultaat wat verouderd is zodra de gebruiker 1x clickt.
Afgezien daarvan hoef je niet te weten of er andere windows voor je staan. Dat kan je op Vista nogal wat problemen gaan opleveren (icm Aero)

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

Je kan alle windows af lopen en sorteren op Z waarde, en daarna kijken of jouw window overlapt word door een window met een lagere Z met GetWindowRect() oid.

-niks-


Acties:
  • 0 Henk 'm!

  • Guldan
  • Registratie: Juli 2002
  • Laatst online: 20:58

Guldan

Thee-Nerd

Topicstarter
@MLM dat probeerde ik eigenlijk ook, alleen gaat het mij wat lastig af zonder een klein voorbeeldje:
Ik kan met getTopWindow de hwnd van de bovenste window halen. hoe kan ik deze dan sorteren op z waarde? Ik heb al een boel gezocht maar weinig nuttigs gevonden.

You know, I used to think it was awful that life was so unfair. Then I thought, wouldn't it be much worse if life were fair, and all the terrible things that happen to us come because we actually deserve them?


Acties:
  • 0 Henk 'm!

  • leuk_he
  • Registratie: Augustus 2000
  • Laatst online: 15-07 15:35

leuk_he

1. Controleer de kabel!

MLM schreef op maandag 19 januari 2009 @ 13:40:
Je kan alle windows af lopen en sorteren op Z waarde, en daarna kijken of jouw window overlapt word door een window met een lagere Z met GetWindowRect() oid.
Waarbij je ervan uit gaat dat windows rechthoekig vierkant :X zijn... wat niet altijd het geval is.

[ Voor 3% gewijzigd door leuk_he op 19-01-2009 15:28 ]

Need more data. We want your specs. Ik ben ook maar dom. anders: forum, ff reggen, ff topic maken
En als je een oplossing hebt gevonden laat het ook ujb ff in dit topic horen.


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
leuk_he schreef op maandag 19 januari 2009 @ 14:48:
[...]

Waarbij je ervan uit gaat dat windows vierkant zijn... wat niet altijd het geval is.
Nou ja; in principe zijn windows altijd rechthoekig (vierkant sowieso niet :P ); dat er binnen die rectangle echter maar een bepaald oppervlak gebruikt wordt (dus delen transparant) is andere koek ;)

[ Voor 3% gewijzigd door RobIII op 19-01-2009 15:04 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

Goed, ik heb dit nooit gedaan maar met MSDN ernaast denk ik dat het zoiets zal zijn (semi-code):

- Loop over GetWindowNext() met GW_HWNDPREV om door de Z-order naar boven te lopen
- Voor elke window die je terugkrijgt, gebruik GetWindowRect() om het oppervlak van dat window te krijgen
- Kijk of het oppervlak van jouw window binnen het oppervlak van stap 2 valt
- Zo ja -> er is een window dat jouw window overlapt
- Zo nee -> volgende window

Om dit te verbeteren moet je ook nog rekening houden met transparency (is jouw window zichtbaar ACHTER een andere window), en de mogelijkheid dat de linkerhelft van je window achter A valt, en de rechterhelft achter B (dus, bijhouden welke gebieden onzichtbaar zijn)

Maar als sidenote, is er niet een VEEL simpeler oplossing, dit gewoon laten doen door windows. Wacht op een WM_PAINT message voor je je window update. Als je window onzichtbaar is (zials bepaald door windows zelf), ga je volgens mij geen WM_PAINT messages krijgen :)

-niks-


Acties:
  • 0 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
En als je deels zichtbaar bent, dan krijg je WM_PAINTs voor de zichtbare delen. Wekrt netjes, ook op Vista.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 20:52

.oisyn

Moderator Devschuur®

Demotivational Speaker

Kon je niet het zichtbare region van je Window opvragen op een of andere manier? Ik heb even zitten zoeken maar ik kan het niet vinden. Dan is het gewoon een kwestie van testen of je window region leeg is of niet.
MLM schreef op maandag 19 januari 2009 @ 15:55:
Goed, ik heb dit nooit gedaan maar met MSDN ernaast denk ik dat het zoiets zal zijn (semi-code):

- Loop over GetWindowNext() met GW_HWNDPREV om door de Z-order naar boven te lopen
- Voor elke window die je terugkrijgt, gebruik GetWindowRect() om het oppervlak van dat window te krijgen
- Kijk of het oppervlak van jouw window binnen het oppervlak van stap 2 valt
- Zo ja -> er is een window dat jouw window overlapt
- Zo nee -> volgende window

Om dit te verbeteren moet je ook nog rekening houden met transparency (is jouw window zichtbaar ACHTER een andere window), en de mogelijkheid dat de linkerhelft van je window achter A valt, en de rechterhelft achter B (dus, bijhouden welke gebieden onzichtbaar zijn)
Dat is dus handiger met regions. Sowieso kan een window rect een heel stuk groter zijn dan z'n region. Als je het op die manier wilt doen, begin dan met de region van je eigen window, en trek daar dan vervolgens alle regions van non-transparent bovengelegen windows vanaf. En eigenlijk zou je 'm ook nog moeten ANDen met de desktop region. Hou je geen empty region over, dan ben je nog zichtbaar.

Het punt is wel dat GetNextWindow() nogal flakey is. De volgorde kan wijzigen terwijl je er doorheen loopt, waardoor je windows kunt overslaan of in een infinite loop terecht komt. Je kunt beter met EnumWindows()/EnumChildWindows() aan de slag, omdat die gebruik maken van een shapshot.

[ Voor 78% gewijzigd door .oisyn op 20-01-2009 13:25 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Guldan
  • Registratie: Juli 2002
  • Laatst online: 20:58

Guldan

Thee-Nerd

Topicstarter
Ok, ik heb na een hele poos prutsen een oplossing gevonden het is misschien niet de netste/beste oplossing maar het werkt. Ik heb een voorbeeld gevonden op een forum wat ik aangepast heb.
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int GetWindowLevel(HWND MyWindow)
{
     //de vector waarin de window hwnds opgeslagen worden
      vector<HWND> vWindows;
      HDESK hDesk = GetThreadDesktop(GetCurrentThreadId());
      
     //Geef enumDesktopWindows een link naar de callback mee
     WNDENUMPROC lpEnumProc = (WNDENUMPROC)ScreenHelper::EnumChildProc;
      EnumDesktopWindows(hDesk, lpEnumProc, (LPARAM)&vWindows);
      //loop door de lijst en kijk op welk nr je window staat (z order)
    for(int i=0;i < vWindows.size(); i++)
    {
        HWND sel = vWindows.at(i);
        if(sel == MyWindow)
        {
            return i+1;
        }
    }
    return 0;
}   


Nu de code voor de callback.

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)
{
    
      if (!::IsWindowVisible(hwnd))
            return TRUE;

      if (::GetParent(hwnd)) {
            return TRUE;
      }

      RECT rc;
      ::GetWindowRect(hwnd, &rc);

      if (rc.bottom==0 && rc.left==0 && rc.right==0 && rc.top==0)
            return TRUE;

      if (::IsIconic(hwnd))
            return TRUE;




      char windowText[256];
      if (::GetWindowText(hwnd, (LPWSTR)windowText, sizeof(windowText))) 
      { 
        
            RECT rtmp, rme;
            GetWindowRect(myWindow, &rme);
            if (IntersectRect(&rtmp, &rme, &rc))
            {      //found an intersection - but we dont know
                  //whether this window is on top of ours or not
                  std::vector<HWND>* pvWindows = (std::vector<HWND>*)lParam;
                  pvWindows->push_back(hwnd);
            } 
                
      }   
      return TRUE; 
}


Met deze code kan je zien op welk z order een venster staat. Dat was wat ik nodig was!. Allemaal bedankt voor de hulp. Door jullie replies wist ik tenminste waar ik het moest zoeken :)

You know, I used to think it was awful that life was so unfair. Then I thought, wouldn't it be much worse if life were fair, and all the terrible things that happen to us come because we actually deserve them?

Pagina: 1