Jak zjistit o kolik okno přesahuje? – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Jak zjistit o kolik okno přesahuje? – C / C++ – Fórum – Programujte.comJak zjistit o kolik okno přesahuje? – C / C++ – Fórum – Programujte.com

 

oxidián0
Grafoman
8. 9. 2015   #1
-
0
-

Jak zjistit o kolik okno přesahuje mimo viditelnou část obrazovky? Mám dvě okna v aplikaci. Když otevřu mapu, tak mi okno s mapou o přesahuje obrazovku a tak chci vypočítat novou pozici pro obě okna.

Nahlásit jako SPAM
IP: 78.45.87.–
ondrej39+1
Věrný člen
8. 9. 2015   #2
-
0
-

#1 oxidián
Zjisti si aktuální rozlišení monitoru, zjisti si pozici a velikost okna (pozice se většinou váže k levému hornímu rohu okna od levého horního rohu pracovní plochy), přičti k pozici šířku a výšku okna, porovnej, zda je přičtená šířka nebo výška větší než zjištěné rozlišení monitoru a máš přesah.

Všechno se dá zjistit přes WinAPI.

Nahlásit jako SPAM
IP: 79.141.243.–
Inject all the dependencies!
ondrej39+1
Věrný člen
8. 9. 2015   #3
-
0
-

#3 oxidián
Projdi si dokumentaci na WinAPI, je tam všechno popsané.

Nahlásit jako SPAM
IP: 79.141.243.–
Inject all the dependencies!
Radek Chalupa
~ Redaktor
+1
Super člen
10. 9. 2015   #4
-
0
-

#1 oxidián
Takhle  nějak zjistíš pracovní oblast obrazovky/monitoru:

 RECT rect_work;

        if (primarni_monitor)
        {
            if (!SystemParametersInfo(SPI_GETWORKAREA, 0, &rect_work, 0))
                kriticke_ukonceni();
        }
        else
        {
            HMONITOR hmonitor = MonitorFromWindow(hwnd_, MONITOR_DEFAULTTONEAREST);
            _ASSERTE(hmonitor != nullptr);
            if (hmonitor == nullptr)
                kriticke_ukonceni();
            MONITORINFOEX mi;
            memset(&mi, 0, sizeof(mi));
            mi.cbSize = sizeof(mi);
            if (!GetMonitorInfo(hmonitor, &mi))
            {
                if (!SystemParametersInfo(SPI_GETWORKAREA, 0, &rect_work, 0))
                    kriticke_ukonceni();
            }
            else
                memcpy(&rect_work, &mi.rcWork, sizeof(rect_work));
        }

a pak potřebuješ GetWindowRect pro zjištění polohy a rozměrů okna

pak trochu počítání souřadnic

a nakonec (v připadě potřeby) zavolat fci SetWindowPos

Radek Chalupa
- individuální konzultace, školení programování (C/C++, WinAPI, COM, ActiveX, ATL, C#, NET Framework, MFC)
- vývoj software na zakázku
http://www.radekchalupa.cz

Nahlásit jako SPAM
IP: 89.177.51.–
oxidián0
Grafoman
11. 9. 2015   #5
-
0
-

Teď už to mám hotové. Ale je tu malinký zádrhel a tak bych se vás chtěl zeptat jestli nevíte v čím to je.

void OnMAP_Reset(HWND mapview, bool resize)
{
	if (resize)
	{
	RECT MapView, MainWind, Desktop;
  const HWND hDesktop = GetDesktopWindow();
	// get bounding rectangle of window (client area)
  GetWindowRect(mapview, &MapView); 
  GetWindowRect(wrapper.handles.hPropSheet, &MainWind);
  GetWindowRect(hDesktop, &Desktop);
	
  
	// JUST FOR INTEREST:
	RECT rcClient;
    POINT border; 
	GetClientRect(mapview, &rcClient); // get size of Window
    border.x = (MapView.right - MapView.left) - rcClient.right;    
    border.y = (MapView.bottom - MapView.top) - rcClient.bottom;    
	int border_width = border.x/2;
	int title_height = border.y-border.x;
  // int mapViewWidth = MapView.right; // INCORRECT! USE minsize
  int mainWindWidth = MainWind.right-MainWind.left;
  int screenWidth = Desktop.right;
  int screenHeight = Desktop.bottom;
  int posx = 0;
  int posy = 0;
  
  POINT minsize = CalculateMinSize(mapview);
  // The rest of screen is bigger than width of Map Viewer
  if (screenWidth - mainWindWidth >= minsize.x)
      {
      posx = (int) ((screenWidth - mainWindWidth - minsize.x) / 3); 
      SetWindowPos(wrapper.handles.hPropSheet, NULL, posx, posy, 0, 0,
				SWP_NOSIZE | SWP_NOZORDER);
      posx = (int) ((screenWidth - mainWindWidth - minsize.x) / 3 * 2 + mainWindWidth);
			SetWindowPos(mapview, NULL, posx, posy, minsize.x, minsize.y,
				SWP_NOZORDER);
      }
  else
      {
      SetWindowPos(wrapper.handles.hPropSheet, NULL, 0, posy, 0, 0,
				SWP_NOSIZE | SWP_NOZORDER);        
      // If the windows cannot fit screen, shit the Map Viewer a bit to left (overlap main window)
      posx = mainWindWidth + minsize.x > screenWidth ? mainWindWidth - 
             (-screenWidth+mainWindWidth+minsize.x>=41?41:(-screenWidth+mainWindWidth+minsize.x) )
            : mainWindWidth;  
      SetWindowPos(mapview, NULL, posx, posy, minsize.x, minsize.y,
				SWP_NOZORDER);
      }
    posx = (screenWidth - mainWindWidth - minsize.x) / 3; 
     
  }

	// Erase everything and re-draw
	HandleRefresh(mapview, TRUE);
}

CalculateMinSize spolehlivě vrátí velikost okna, kterou potřebuji.

Mám rozlišení 800 x 600 px. Hlavní okno je obdelníkové na ležato a je vlevo, druhé okno má být vpravo vedle něj a je čtvercové + statusbar. Nejdříve otevřu malou mapu, ta se krásně vleze na obrazovku, skočí to tedy do první větve if a pozice obou oken se upraví tak, aby byly okna rovnoměrně od sebe. Pak otevřu větší mapu (dojde k aktualizaci rozměru okna a načte se jiný obrázek do okna č. 2), větší čtverec (okno) se nevleze na obrazovku, takže hlavní okno má souřadnici x = 0 a souřadnice x u pravého okna je šířka hlavního okna (č. 1) mínus cca 40px. Takže dokde k překryvu oken. Pak znovu načtu první mapu a ejhle, rozměr okna asi není ten samý co byl, i když hodnoty ukazují stejnou hodnotu minsize (první větev, druhý řádek). Jde o to, že okno se jeví jakoby trochu zmenšené takže se mapka nevleze do okna a tj. asi ořez 20px zprava a 20px dole. U toho prvního okna nebyly posuvníky, teď se tam ale posuvníky objevily a já nechápu proč. Takže při spuštění programu a otevření malé mapky posuvníky tam nejsou. Po otevření další mapky a znovu otevření první mapky tam jsou posuvníky. Ty posuvníky asi ořízly mapku. Otázka je proč tam jsou posuvníky? Potažmo jak se jich zbavit?
 

V proceduře dlgproc toho okna MapView jsou mimo jiné tyto věci:

	case WM_SIZE:
		UpdateScrollbars(window, LOWORD(lParam), HIWORD(lParam));
		SendMessage(data.statusbar, WM_SIZE, 0, 0);
		break;

	case WM_HSCROLL:
		OnWM_HSCROLL(window, LOWORD(wParam), HIWORD(wParam));
		break;

	case WM_VSCROLL:
		OnWM_VSCROLL(window, LOWORD(wParam), HIWORD(wParam));
		break;
Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
12. 9. 2015   #6
-
0
-

A v obou případech kdy se nastavuje velikost toho menšího okna lParam je 20775201, takže WM_SIZE asi scrollbary nevytváří...

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
12. 9. 2015   #7
-
0
-

Už jsem zjistil co zapíná ty scrollbary:

posx = (int) ((screenWidth - mainWindWidth - minsize.x) / 3 * 2 + mainWindWidth);
SetWindowPos(mapview, NULL, posx, posy, minsize.x, minsize.y,
					SWP_NOZORDER);


SetWindowPos. Jak to udělat, aby se scrollbary nezapnuly? Otevírám jednu a tu samou mapu, která by se měla vejít do okna (rozměr okna je stejný, stejná mapa) ale přesto se tam vytvoří scrollbary. Testem na strukturu SCROLLBARINFO jsem zjistil že pSBI->rgstate[0] == STATE_SYSTEM_INVISIBLE je v prvním případě true, v druhém false. Takže SetWindowPos změní tu informaci, takže musí existovat flag kterým to STATE_SYSTEM_INVISIBLE nevypínat. Jinak bych snad mohl nastavit SCROLLINFO si; SetScrollInfo(window, SB_HORZ, &si, FALSE);

Nahlásit jako SPAM
IP: 78.45.87.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 26 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý