Funkcja zaprzyjaźniona i HINSTANCE

0

Wymyśliłem, że tworze swoją klasę okien. Każde okno wygląda inaczej (w zależności od
podanego pędzla), przy zachowaniu wspólnej klasy(WNDCLASSEX).
Plik .h

#ifndef Nowa_Kontrolka_h_
  #define Nowa_Kontrolka_h_

class Nowa_Kontrolka;

#include<windows.h>
#include<iostream>

LRESULT CALLBACK fZdarz(HWND hWindow, UINT zdarzenie, WPARAM wParam, LPARAM lParam);

class Nowa_Kontrolka
{
  private:
          static int licznik;//liczy ilosc obiektów
          HWND uchwyt;
          HBITMAP tlo;
          static WNDCLASSEX WndClass;
  public:
         Nowa_Kontrolka(HWND Rodzic, HINSTANCE hInst, HBITMAP bitmapa);
         //Zaprzyjaźniam funkcje zdarzeniową, by mogła sięgać po 'tlo'
         friend LRESULT CALLBACK fZdarz(HWND hWindow, UINT zdarzenie, WPARAM wParam, LPARAM lParam);
};

#endif

Plik .cpp

#include"Nowa_Kontrolka.h"
extern HINSTANCE *hInstance;

int Nowa_Kontrolka::licznik = 0;

WNDCLASSEX Nowa_Kontrolka::WndClass = {
                                       sizeof(WNDCLASSEX),
                                       0,
                                       fZdarz,
                                       0,0,
                                       *hInstance,
                                       LoadIcon(NULL, IDI_APPLICATION),
                                       LoadCursor(NULL, IDC_ARROW),
                                       (HBRUSH)COLOR_WINDOW,
                                       NULL,
                                       "Nowa_Kontrolka",
                                       LoadIcon(NULL, IDI_APPLICATION)  };

//******************************************************************************
Nowa_Kontrolka::Nowa_Kontrolka(HWND Rodzic, HINSTANCE hInst, HBITMAP bitmapa)
{
  ++licznik;//stworzono nowy obiekt

  //Jeśli jest to pierwszy obiekt tej klasy
  if( licznik < 2 )
     RegisterClassEx(&WndClass);

  tlo = bitmapa;

  uchwyt = CreateWindowEx( WS_EX_TOOLWINDOW,
                           "Nowa_Kontrolka",
                           "Oto nowa kontrolka",
                           WS_CHILD|WS_OVERLAPPEDWINDOW|WS_VISIBLE,
                           10,10,  100,100,
                           Rodzic,
                           0,
                           hInst,
                           NULL);
}

//******************************************************************************
LRESULT CALLBACK fZdarz(HWND hWindow, UINT zdarzenie, WPARAM wParam, LPARAM lParam)
{
   switch(zdarzenie)
   {     
      case WM_DESTROY:
           {
              PostQuitMessage(0);
              break;        
           }
      case WM_PAINT:
           {
              HDC hdcKontekst = GetDC(hWindow);
              HDC hdcPamiec = CreateCompatibleDC(hdcKontekst);
              DeleteObject( SelectObject(hdcPamiec, tlo) );//błąd - 'tlo' undeclared

              BITMAP rozmiar;
              GetObject(hdcPamiec, sizeof(BITMAP), &rozmiar);

              BitBlt(hdcKontekst,  200,    100,   rozmiar.bmWidth, rozmiar.bmHeight,
                     hdcPamiec, 0, 0, SRCCOPY);  

              DeleteDC(hdcPamiec);
              ReleaseDC(hWindow, hdcKontekst);      
              break;
           }
   } 

   return DefWindowProc(hWindow, zdarzenie, wParam, lParam);
}

Nie wiem skąd ten błąd skoro funkcja jest zaprzyjaźniona. Z tego co wiem to wskaźnik "*hInstance"
tu nie pasuje, bo musi być on znany już w trakcie kompilacji i okno w ogóle się nie wyświetli.
Niestety na razie tego nie sprawdze, bo mam inny błąd. Proszę o pomoc.
</php>

0

Plik .cpp
exern HINSTANCE hInstance; //HINSTANCE?

sizeof(WNDCLASSEX),
0,
fZdarz,
0,0,
hInstance, //hInstance..? po co przekazywac przez wskaznik? patrz wyzej.. przekaz to miedzy modulami przez wartosc, to i tak jest wartosc stala przez caly czas dzialania programu

////

extern HINSTANCE hInstance; < to oznacza, ze to zmeinna globalna z INNEGO pliku .cpp. nie masz innego pliku.cpp z taka zmienna globalna, wiec wywala ci sie podczas linkowania ze brak symbolu..

///

a sama wartosc hInstance dostajesz bodajze w parametrac winmain()
http://msdn2.microsoft.com/en-us/library/ms633559(VS.85).aspx

ps...wez sie zainteresuj jakims MFC albo ATL zamiast je pisac z palca od zera :)

0
//Zaprzyjaźniam funkcje zdarzeniową, by mogła sięgać po 'tlo'

by mogła sięgać po 'tlo' fZdarz musi wiedzieć którego obiektu i z jakiej klasy jest to tlo. Funkcja ta nie jest metodą, ale odwołujesz się do składowej klasy jakby była.

Nie wiem skąd ten błąd skoro funkcja jest zaprzyjaźniona.

Funkcja zaprzyjaźniona != metoda ;)

Z tego co wiem to wskaźnik "*hInstance" tu nie pasuje, bo musi być on znany już w trakcie kompilacji i okno w ogóle się nie wyświetli.

Nie wiem po co to hInstance jeżeli przekazujesz tą wartość w konstruktorze?

Reasumując: fZdarz powinna dostać wskaźnik do obiektu klasy Nowa_Kontrolka. Można tak to zrobić (mogą być błędy):

uchwyt = CreateWindowEx( WS_EX_TOOLWINDOW,
                           "Nowa_Kontrolka",
                           "Oto nowa kontrolka",
                           WS_CHILD|WS_OVERLAPPEDWINDOW|WS_VISIBLE,
                           10,10,  100,100,
                           Rodzic,
                           0,
                           hInst,
                           this); //<---

[...]

case WM_CREATE:
{   
   CREATESTRUCT *pcs=(CREATESTRUCT*)lParam;
   SetWindowLongPtr(hWindow,GWLP_USERDATA,pcs->lpCreateParams);
   return 0;
}

default:
{
    Nowa_Kontrolka* ptr=(Nowa_Kontrolka*)GetWindowLongPtr(hWindow, GWLP_USERDATA);
    if(ptr)return ptr->procedura_okienkowa_jako_metoda(....);
}
    [...]
0

Kurde. Teraz to już nic nie wiem [glowa].

"ps...wez sie zainteresuj jakims MFC albo ATL zamiast je pisac z palca od zera :)"

Mógłbyś bardziej przybliżyć temat? Co to w ogóle jest?

Mój nauczyciel od programowania mówi, żebym skorzystał z czegoś takiego jak GUI, zamiast pisać wszyściutko od zera. Skoro są gotowe rzeczy, to po co w ogóle zajmować się nauką WINAPI ? ;-).

0

Co to w ogóle jest?

Obiektowy odpowiednik WinAPI. Jest jeszcze VCL (C++ Builder), wxWidgets, Qt, SmartWin itd.

0

Na Windowsa najlepszy jest Windows Forms w .NET

0

A tak w ogole hInstace wcale nie trzeba przekazywac bo hInstance=GetModuleHandle(NULL) o ile dobrze pamietam - to zadziala zawsze chyba ze tworzysz okna w bibliotece dll.

Skoro są gotowe rzeczy, to po co w ogóle zajmować się nauką WINAPI ? ;-)

Własnie. Chociaz jednak czasami znajomosc WinApi moze sie przydac, ale nie az tak czesto. MFC chyba tez juz raczej nie warto sie uczyc.

0

Gdzie mógłbym dostać informacje na temat Windows Forms w .NET lub GUI, jak zacząć, <ort>skąd</ort> itp.
Proszę o odpowiedz :-|

0

Gdzie? Wszędzie - poszukaj a znajdziesz. Pełno jest kursów do .NET, na msdn na stronie Microsoftu i w helpie od Visual C# tez (najlepiej jak laczy sie z msdn przez internet).

Wspomniane wxWidgets ja osobiscie tez bardzo lubie wiec radzilbym albo C#/NET albo wxWidgets.

wxWidgets ma jeszcze ta zalete ze utworzone aplikacje mozna odpalic na kazdym kompie, a .NET wymagaja zainstalowanego .NET framework w odpowiedniej wersji.
Jezeli jednak chcesz sie nauczyc czegos, co ulatwi znalezienie pracy w przyszlosci, to C# i NET uczyc sie chyba najbardziej warto.

Do wxWidgets polecam wxDevC++ i dokumentacje wxWidgets.

0

Co do windows forms i c++ to poszukaj na torrentach kursu "global profit". Opisuje visual ee 2005.

Są to filmiki pokazujące jak się to je. Nie jest to nic wielkiego ale na początek da Ci pewien obraz jak to się robi.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0