LittleJoe Posted October 6, 2008 at 08:49 PM Report #215906 Posted October 6, 2008 at 08:49 PM 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!
Triton Posted October 6, 2008 at 09:02 PM Report #215910 Posted October 6, 2008 at 09:02 PM Claro que existe. http://en.wikipedia.org/wiki/WTL http://en.wikipedia.org/wiki/Microsoft_Foundation_Class_Library Já ouvi dizer que WTL é muito bom e leve, ao contrário de MFC. <3 life
M6 Posted October 6, 2008 at 10:04 PM Report #215937 Posted October 6, 2008 at 10:04 PM 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."
Marfig Posted October 6, 2008 at 10:17 PM Report #215942 Posted October 6, 2008 at 10:17 PM 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.
LittleJoe Posted October 7, 2008 at 07:28 PM Author Report #216131 Posted October 7, 2008 at 07:28 PM Muito obrigado malta, voçês são todos porreiros. 😉 SE O MILTON FRIEDMAN AINDA FOSSE VIVO, SERIA POR POUCO TEMPO. APANHAVAM-NO LOGO E ENFORCAVAM-NO NUM POSTE!
LittleJoe Posted October 7, 2008 at 07:32 PM Author Report #216133 Posted October 7, 2008 at 07:32 PM 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!
Marfig Posted October 7, 2008 at 08:06 PM Report #216143 Posted October 7, 2008 at 08:06 PM 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.
LittleJoe Posted October 7, 2008 at 08:12 PM Author Report #216146 Posted October 7, 2008 at 08:12 PM 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!
LittleJoe Posted October 8, 2008 at 10:03 PM Author Report #216478 Posted October 8, 2008 at 10:03 PM 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!
Triton Posted October 8, 2008 at 10:12 PM Report #216482 Posted October 8, 2008 at 10:12 PM Só por curiosidade, porque não usas WTL? Fazer um wrapper a uma API desta dimensão não é tarefa fácil. 😛 <3 life
LittleJoe Posted October 9, 2008 at 05:21 PM Author Report #216579 Posted October 9, 2008 at 05:21 PM 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!
TheDark Posted October 9, 2008 at 07:23 PM Report #216606 Posted October 9, 2008 at 07:23 PM 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.
Triton Posted October 9, 2008 at 07:29 PM Report #216607 Posted October 9, 2008 at 07:29 PM Acho que a versão 2008 Express não trás ATL, por isso tens de instalar o Platform SDK. <3 life
TheDark Posted October 9, 2008 at 08:13 PM Report #216625 Posted October 9, 2008 at 08:13 PM Acho que a versão 2008 Express não trás ATL, por isso tens de instalar o Platform SDK. É o ponto 2 do tutorial 😉 : 2. Download and install the Platform SDK, and update the Visual C++ setting as detailed here. http://www.codeproject.com/KB/wtl/WTLExpress.aspx Desaparecido.
Marfig Posted October 9, 2008 at 10:18 PM Report #216671 Posted October 9, 2008 at 10:18 PM 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.
LittleJoe Posted October 9, 2008 at 10:39 PM Author Report #216675 Posted October 9, 2008 at 10:39 PM 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!
Triton Posted October 9, 2008 at 10:56 PM Report #216681 Posted October 9, 2008 at 10:56 PM Não é o DirectX SDK. Mas sim o Platform SDK. <3 life
LittleJoe Posted October 10, 2008 at 10:05 PM Author Report #216980 Posted October 10, 2008 at 10:05 PM 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!
Triton Posted October 10, 2008 at 10:18 PM Report #216989 Posted October 10, 2008 at 10:18 PM O meu ficou instalado em C:\Program Files\Platform SDK. Mas isso não será o auto-extract para depois iniciar a instalação propriamente dita? <3 life
Marfig Posted October 10, 2008 at 10:54 PM Report #216999 Posted October 10, 2008 at 10:54 PM 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.
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now