Jump to content

Recommended Posts

Posted

Boas, mais uma vez!

A Programação Orientada ao Objecto (POO) simplifica muito as coisas (e de que maneira). Infelizmente o Win32 API não é orientado ao objecto. Estou a dar os primeiros passos em Win32 API e até já tentei incorporá-lo em classes (um pouco ingénuamente, confesso), mas, evidentemente, deu buraco.

Será que poderá haver uma espécie de "casamento" entre a POO (neste caso em C++) e o Win32 API?

Gostaria muito que me dessem a resposta...  :dontgetit:

SE O MILTON FRIEDMAN AINDA FOSSE VIVO, SERIA POR POUCO TEMPO. APANHAVAM-NO LOGO E ENFORCAVAM-NO NUM POSTE!

  • Replies 50
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Posted

A API do Windows é C pura.

Tipicamente fazes uma chamada às funções com a estrutura e recebes o tamanho, depois alocas a memória de acordo com o tamanho recebido para a estrutura em causa e voltas a chamar a função com essa "instância" da estrutura, e, por fim, recebes a estrutura com os valores que procuravas...

10 REM Generation 48K!
20 INPUT "URL:", A$
30 IF A$(1 TO 4) = "HTTP" THEN PRINT "400 Bad Request": GOTO 50
40 PRINT "404 Not Found"
50 PRINT "./M6 @ Portugal a Programar."

 

Posted

Yup. E ainda wxWidgets. E ainda Qt...

Basicamente o OOP pode servir como wrapper a praticamente qualquer tipo de código procedural. No caso de funções pode também servir como um layer separando o programador da implementação.

Pode ser tão simples como:

namespace esconder_api {

    int uma_funcao_da_api() { /* ... */ }

}

class obj {

    public:

        using namespace esconder_api;
       
        /* ... */

        int metodo() { return uma_funcao_da_api(); }

};

int main() {

    obj foo();

    foo.metodo() // chama a API uma_funcao_da_api()

}

O namespace "esconde" a API. E OOP vai agir como um wrapper e um layer, Expondo as funções e objectos da API. É assim que o MFC, WTL, WxWidgets e Qt são basicamente desenhados.

Posted

Yup. E ainda wxWidgets. E ainda Qt...

Basicamente o OOP pode servir como wrapper a praticamente qualquer tipo de código procedural. No caso de funções pode também servir como um layer separando o programador da implementação.

Pode ser tão simples como:

namespace esconder_api {

    int uma_funcao_da_api() { /* ... */ }

}

class obj {

    public:

        using namespace esconder_api;
       
        /* ... */

        int metodo() { return uma_funcao_da_api(); }

};

int main() {

    obj foo();

    foo.metodo() // chama a API uma_funcao_da_api()

}

O namespace "esconde" a API. E OOP vai agir como um wrapper e um layer, Expondo as funções e objectos da API. É assim que o MFC, WTL, WxWidgets e Qt são basicamente desenhados.

Genial. Mas também servirá para a 'int WINAPI WinMain()'?

SE O MILTON FRIEDMAN AINDA FOSSE VIVO, SERIA POR POUCO TEMPO. APANHAVAM-NO LOGO E ENFORCAVAM-NO NUM POSTE!

Posted

Sem dúvida. Não de forma tão simples, é claro.

Mas todas as frameworks descritas acima implementam os seus próprios pontos de entrada.

Thanks!  😉

SE O MILTON FRIEDMAN AINDA FOSSE VIVO, SERIA POR POUCO TEMPO. APANHAVAM-NO LOGO E ENFORCAVAM-NO NUM POSTE!

Posted

Yup. E ainda wxWidgets. E ainda Qt...

Basicamente o OOP pode servir como wrapper a praticamente qualquer tipo de código procedural. No caso de funções pode também servir como um layer separando o programador da implementação.

Pode ser tão simples como:

namespace esconder_api {

    int uma_funcao_da_api() { /* ... */ }

}

class obj {

    public:

        using namespace esconder_api;
       
        /* ... */

        int metodo() { return uma_funcao_da_api(); }

};

int main() {

    obj foo();

    foo.metodo() // chama a API uma_funcao_da_api()

}

O namespace "esconde" a API. E OOP vai agir como um wrapper e um layer, Expondo as funções e objectos da API. É assim que o MFC, WTL, WxWidgets e Qt são basicamente desenhados.

Olá outra vez Marfig.

Escrevi um programa muito básico e simples que, a única coisa que faz é criar uma janela 640x480 pixels, com o intuito de tentar ilustrar a citação acima:

// Win32Classes.cpp

#include <windows.h>

namespace WndProcNameSpace
{
// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, 
	                           WPARAM wParam, LPARAM lParam)
{
	switch(msg)
	{
	case WM_CLOSE:
		DestroyWindow(hwnd);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hwnd, msg, wParam, lParam);
	}

	return 0;
}
}

class WndProcClass
{
public:
LRESULT CALLBACK WProc()
{
	return (LRESULT)WndProcNameSpace::WndProc;
}
};

namespace WinMainNameSpace
{
const char g_szClassName[] = "myWindowClass";
WndProcClass wndProc; // Classe 'WndProcClass'.

int WMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                 LPSTR lpCmdLine, int nCmdShow,
                 LPCSTR windowTitle, int windowWidth, int windowHeight)
{
	WNDCLASSEX wc;
	HWND hwnd;
	MSG Msg;

	//Step 1: Registering the Window Class
	wc.cbSize		 = sizeof(WNDCLASSEX);
	wc.style		 = 0;
	wc.lpfnWndProc	 = (WNDPROC)wndProc.WProc(); // 'WndProcClass wndProc'.
	wc.cbClsExtra	 = 0;
	wc.cbWndExtra	 = 0;
	wc.hInstance	 = hInstance;
	wc.hIcon		 = LoadIcon(NULL, IDI_APPLICATION);
	wc.hCursor		 = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
	wc.lpszMenuName  = NULL;
	wc.lpszClassName = g_szClassName;
	wc.hIconSm		 = LoadIcon(NULL, IDI_APPLICATION);

	if(!RegisterClassEx(&wc))
	{
		MessageBox(NULL, "Window Registration Failed!", "Error!",
		                     MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}

	// Step 2: Creating the Window
	hwnd = CreateWindowEx(
		WS_EX_CLIENTEDGE,
		g_szClassName,
		windowTitle, // Parâmetro 'windowTitle'.
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, CW_USEDEFAULT, windowWidth, windowHeight, // Parâmetros 'windowWidht' e 'windowHeight'.
		NULL, NULL, hInstance, NULL);

	if(hwnd == NULL)
	{
		MessageBox(NULL, "Window Creation Failed!", "Error!",
		                     MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}

	ShowWindow(hwnd, nCmdShow);
	UpdateWindow(hwnd);

	// Step 3: The Message Loop
	while(GetMessage(&Msg, NULL, 0, 0) > 0)
	{
		TranslateMessage(&Msg);
		DispatchMessage(&Msg);
	}

	return Msg.wParam;
}
}

class WinClass
{
char* title;
int width, height;

public:
WinClass(char* title, int width, int height);

int Wmain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
	      LPSTR lpCmdLine, int nCmdShow)
{
	return WinMainNameSpace::WMain(hInstance, hPrevInstance,
                                                                               lpCmdLine, nCmdShow,
                                                                                                    (LPCSTR)title, width, height);
}
};

WinClass::WinClass(char* title, int width, int height)
{
this->title = title;
this->width = width;
this->height = height;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
            LPSTR lpCmdLine, int nCmdShow)
{
WinClass* winClass = new WinClass("The Title of my Window", 640, 480);

winClass->Wmain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);

delete winClass;
winClass = NULL;
}

O programa em si funciona, pois compilei o código fonte sem erros nem warnings. A questão é: embora muito simples e básico, será este um exemplo razoável da citação acima?

Agradecia muito que desses o teu parecer.  😛

SE O MILTON FRIEDMAN AINDA FOSSE VIVO, SERIA POR POUCO TEMPO. APANHAVAM-NO LOGO E ENFORCAVAM-NO NUM POSTE!

Posted

Só por curiosidade, porque não usas WTL? Fazer um wrapper a uma API desta dimensão não é tarefa fácil. 😛

Instalei o WTL, mas não funciona. Quando tento fazer a compilação dá o seguinte erro:

"fatal error C1083: Cannot open include file: 'atlbase.h': No such file or directory"

Já pensei que será por eu usar o Visual C++ 2008 Express. Será?  :dontgetit:

SE O MILTON FRIEDMAN AINDA FOSSE VIVO, SERIA POR POUCO TEMPO. APANHAVAM-NO LOGO E ENFORCAVAM-NO NUM POSTE!

Posted

Já pensei que será por eu usar o Visual C++ 2008 Express. Será?  :dontgetit:

Penso que sim. Pelo menos no Wiki diz o seguinte:

The freely available Microsoft Visual C++ 2005 Express Edition and Microsoft Visual C++ Codename Orcas Express Edition can be configured to handle WTL development: this requires some careful steps documented here.

Supostamente, é só seguires os passos descritos no link.

Desaparecido.

Posted

O programa em si funciona, pois compilei o código fonte sem erros nem warnings. A questão é: embora muito simples e básico, será este um exemplo razoável da citação acima?

Agradecia muito que desses o teu parecer.

Desculpa-me LittleJoe. Vi este post à que tempos, pensei responder mais tarde nesse dia e desde então... nunca mais me lembrei 😉

...

Nope. Não é assim que o fazes 🙂

Mas a ideia está lá. Vi que sim. O problema, é que para fazeres um wrap à volta de uma API tens que mexer nas próprias declarações da API e não nas definições. O que neste caso, significa alterares windows.h.  Seria aí, onde os vários elementos da API são declarados, que faria sentido  envolver tudo dentro de namespaces. Não que o devas fazer hehe...

O que fizeste no teu código foi criares namespaces à volta de definições e não de declarações.

Posted

Muito obrigado Malta.  😉

Acho melhor seguir o teu conselho Marfig e tirar da cabeça os wraps no windows.h. Estou a ver que nem sabia no que é que me metia.  ?

Já agora, falaram no SDK. Se se estão a referir ao Microsoft DirectX SDK de Agosto de 2007, então já o tenho, mas não consigo encontrar o 'atlbase.h'.

SE O MILTON FRIEDMAN AINDA FOSSE VIVO, SERIA POR POUCO TEMPO. APANHAVAM-NO LOGO E ENFORCAVAM-NO NUM POSTE!

Posted

Não é o DirectX SDK. Mas sim o Platform SDK.

Thanks Triton.

Já fiz o download do Platform SDK, no entanto quando abro o self-extractor, aparece uma janela a perguntar-me em que directório quero que os ficheiros extraídos sejam postos. O que é certo é que não faço a mais pequena ideia onde pôr os ficheiros extraídos. Poderás dar-me uma ajuda?  🙂

SE O MILTON FRIEDMAN AINDA FOSSE VIVO, SERIA POR POUCO TEMPO. APANHAVAM-NO LOGO E ENFORCAVAM-NO NUM POSTE!

Posted

Hmm... pessoal, o Visual Studio 2008 Express Edition já vem com a Platform SDK integrada. Não é nada boa ideia instalar a Platform SDK do 2005 Express Edition.

Se quiseres realmente usar WTL com o 2008 Express vais ter que esperar: http://sourceforge.net/forum/forum.php?thread_id=1880196&forum_id=374433

Mas esperar poderá significar para sempre... Houve algumas alterações de fundo no 2008. Para além do SDK integrado, ao contrário do 2005, o 2008 não vem com ATL. Portanto penso que o projecto WTL levou um tiro de morte.

Entretanto há a considerar o que realmente queres, LittleJoe. Tu queres programar na Windows API, MFC, ou queres simplesmente programar para Windows? Porque se for a última, pessoalmente desaconselho WTL mesmo se conseguires arranjar o 2005 Express (ainda o encontras nos torrents juntamente com o SDK). Aqui a ideia será tirares partido de frameworks que simplifiquem o teu trabalho como o wxWidgets e Qt e te permitem um port relativamente fácil das tuas aplicações para outros sistemas operativos.

Mas se quiseres aprender a usar o core da Microsoft, então mais uma vez WTL não é uma boa ideia, porque te afasta do código MFC/ATL  Assim a ideia neste caso será programares em Windows API e ires juntando um dinheiro e comprares a versão Standard ou Professional do Visual Studio 2008 que já incluem então full MFC/ATL support.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.