Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: FullScreen Windows API:lla / uusi esimerkki

JoinTuanJanohon [23.11.2005 18:47:58]

#

Terem,

Edellinen kysymykseni koskien tätä probleemaa ei ollut riittävän hyvin muotoiltu. Nyt yritän paremmin ja toivottavasti selkeämmin:

Oheisesta koodiesimerkistä olen karsinut kaiken ylimääräisen pois. Jäljellä ovat vain funktiot, joilla ikkuna ja sen piirtopinta Windowsiin luodaan. Tämän perusikkunan päälle on sitten rakennettu likimain Borlandin bgi:tä vastaava grafiikkakirjasto.

Ero on siinä, että oheisen raamin päälle rakennettu kirjasto käyttää Windows API:n grafiikkarajapinnan palveluita. WndProc -funktiosta kutsutaan tavallisen main-funktion kaltaista ConsoleMain:ia, jonka jälkeen kontrollia ei halutessaan enää tarvitse palauttaa Windowsille.

(Windows muka kutsuu omavaltaisesti tehtyä ohjelmafunktiota, opettaa lukuisat Windows-oppaat. Ehkä niin, mutta ConsoleMain on eri mieltä, ottaa ohjat käteensä, ja sen jälkeen päinvastoin Windowsta kutsutaan callback:llä silloin, kun halutaan tarkistaa esimerkiksi hiiren, näppäinten, yms. tiloja. Luultavasti siinä SDL-kirjastossa on sama ajatus, mutta varmasti en tiedä, koska en ole siihen perehtynyt.)

Mutta takaisin tähän ongelmaan. Windows tuntuu haluavan väkisin tehdä piirtopinnalle omat tarpeettomat reunansa ja otsikkorivinsä, ikään kuin kaikki koodaajat olisivat niin uusavuttomia, etteivät osaisi halutessaan tehdä huomattavasti näyttävämpiä kehyksiä, otsikkorivejä, valikkoja, jne. Windows siis aliarvioi ja ajattelee, että tuolle tyhmälle koodaajalle pitää piirtää tällaiset valmiit kehykset ja otsikkorivin, jotta se keltanokka saa kyhättyä piirtopinnalleen edes standartin mukaiset kehykset ja helv..n hienon otsikkorivin!

Oheinen Windows raami kääntyy suoraan. Ikoni, rc- ynnä muita Windowsin hienoja resursseja ei tarvita, ne kait jokainen haluaa värkätä mieluummin omin käsin.

KIITÄN etukäteen, jos jokin langanpäässä oleva Windows-spesialisti viitsii muokata koodiesimerkkiä niiltä osin, että se ottaa käyttöönsä koko piirtopinnan ilman raameja ja reunoja. Ikkunan on tarkoitus käyttää aina samaa resoluutiota ja väriskaalaa, joka sillä hetkellä työpöydän ominaisuuksista on määrätty.

#include <windows.h>

BOOL InitInstance(HINSTANCE, int);
ATOM MyRegisterClass(HINSTANCE hInstance);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE n1, LPSTR n2, int nCmdShow)
{
   MSG msg;

   MyRegisterClass(hInstance);

   if (!InitInstance(hInstance, nCmdShow))
   {
      return FALSE;
   }

   while (GetMessage(&msg, NULL, 0, 0))
   {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
   }

   /*********************************
   * Typerä kääntäjä varoittaa, jos *
   * noita tarpeettomia parametrejä *
   * ei käytetä.  Sitten yhtä pöljä *
   * funktio, joka niitä ihmettelee *
   *********************************/
   int DoNotShowWarning(void*, void*);
   DoNotShowWarning(n1, n2); /* none */

   return msg.wParam;
}

int DoNotShowWarning(void *a, void *b)
{
   return a&&b? 1: 0;
}

ATOM MyRegisterClass(HINSTANCE hInstance)
{
   WNDCLASSEX uWin;
   uWin.hIcon=NULL;
   uWin.hIconSm=NULL;
   uWin.cbClsExtra=0;
   uWin.cbWndExtra=0;
   uWin.lpszMenuName=NULL;
   uWin.hInstance=hInstance;
   uWin.style=CS_BYTEALIGNWINDOW;
   uWin.cbSize=sizeof(WNDCLASSEX);
   uWin.lpfnWndProc=(WNDPROC)WndProc;
   uWin.lpszClassName="FullScreenWindows";
   uWin.hCursor=LoadCursor(NULL, IDC_ARROW);
   uWin.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
   return (ATOM) RegisterClassEx((WNDCLASSEX*)&uWin);
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;

   hWnd=CreateWindow("FullScreenWindows", "", WS_MAXIMIZEBOX,
   CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   HDC hdc=GetDC(hWnd);
   MoveWindow(hWnd, 0, 0,
   GetDeviceCaps(hdc, HORZRES),
   GetDeviceCaps(hdc, VERTRES), FALSE);

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
   char *Text="paina näppäintä, ohjelma lopetetaan...";
   PAINTSTRUCT ps;
   HDC hdc;

   switch (message)
   {
      case WM_PAINT:
      hdc=BeginPaint(hWnd, &ps);
      RECT rt;
      GetClientRect(hWnd, &rt);
      DrawText(hdc, Text, strlen(Text), &rt, DT_LEFT);
      EndPaint(hWnd, &ps);
      break;

      case WM_DESTROY:
      case WM_KEYDOWN:
      PostQuitMessage(0);
      break;

      default:
      return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}

Metabolix [23.11.2005 20:14:02]

#

Johan minä noihin kysymykseen edellisessä vastasin. Et vain ilmeisesti viitsinyt itse soveltaa. Toistetaan vielä:

lainaus:

Tutustupa sellaisiin kuin EnumDisplaySettings arvolla ENUM_CURRENT_SETTINGS ja ChangeDisplaySettings flagilla CDS_FULLSCREEN. Ja sitten oli vielä ikkunan tyyli WS_POPUP, ei mitään WS_OVERLAPPEDWINDOW:ta.

Eli toisin sanoen:

//  #include <windows.h>
    DEVMODE asetukset;
    EnumDisplaySettings(0, ENUM_CURRENT_SETTINGS, &asetukset);
    ChangeDisplaySettings(&asetukset, CDS_FULLSCREEN);

    hwnd = CreateWindow(
           "Ikkunaluokka",
           "Kokoruudunikkuna",
           WS_POPUP | WS_VISIBLE,
           0, 0,
           asetukset.dmPelsWidth,
           asetukset.dmPelsHeight,
           GetDesktopWindow(),
           NULL,
           hInstance,
           NULL);

Vaihtoehtoisesti voi vaihtofunktioon laittaa osoittimen paikalle 0, jolloin käytetään rekisteristä löytyviä asetuksia.

JoinTuanJanohon [24.11.2005 09:08:29]

#

KIITOS :D Tyytyväisyyteni on suuri, NYT TOIMII. Kyllä varmasti tutustuin parhaani mukaan aiemmin mainitsemaasi ohjeeseesi, mutta en vain osannut soveltaa niitä noin kompaktisti, kuin sen esimerkissäsi näytit.

Noin yleisestikin pieni koodiesimerkki kertoo aina sata kertaa enemmän, kuin mitä esim. Windows API manuaalin tuhannesta sivusta irti saa.

Paras esimerkki minulla on SiliconGraphis:in grafiikkamanuaalit. Siellä oli muun muassa kokoikkunan käytöstä suunnilleen vastaavanlainen kompakti muutaman rivin esimerkki, jolla koko näytön sai kerralla käyttöön. Sen grafiikkarajapinnan omaksumisessa aika ei siis mennyt manuaalien plaraamiseen, vaan asiat oli jäsennelty niin, että yleiseen kysymykseen/tarpeeseen löytyi saman tien kompakti esimerkki, ja vasta sitten aiheesta kerrottiin syvemmin.

Ainakin minun kääntäjän manuaalit ovat Windows API:n osalta sellaiset, että jokainen yksittäinen hakusana johtaa päättymättömään silmukkaa, ja lopulta jää tunne, että koko API pitäisi tuntea läpikotaisin, jotta jotain omaa grafiikkaa voisi ruveta värkkäämään. Ja jos manuaaleissa on viitsitty laittaa esimerkki, se on ylellisyyttä. Toisaalta lyhinkin esimerkki omissa manuaaleissani sisltää heti 500-1000 koodiriviä, Windows yrittää siis kaataa kaiken niskaan kerralla, tai ei mitään.

Metabolix [24.11.2005 11:27:47]

#

Ihan Googleen kirjoittamalla löytyy suoraan funktion kuvaus ja minkä tyyppisiä arvoja sille pitää antaa. Ei siinä tarvitse kovin paljon lukea. Sieltä minäkin nämä opin (ja löysin, vaikka en tiennyt funktion nimeä).

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta