[win32] - creating controls using class's
(i'm using a console for test them... i don't know if it's a problem or not)
for now i'm trying creating the label:
label.h:
Code:
#include <windows.h>
#include <iostream>
class label
{
private:
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;
}
public:
label(HWND value)
{
HWND hwnd;
MSG Msg;
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
"STATIC",
"hello world",
SS_LEFT|WS_CHILD|WS_VISIBLE,
0, 0, 100, 100,
value,
NULL,
GetModuleHandle(NULL),
NULL);
if (hwnd==0) cout << "erro";
ShowWindow(hwnd,SW_SHOW);
}
};
main.cpp:
Code:
#include "label.h"
int main()
{
label b(GetForegroundWindow());
return 0;
}
the label isn't created... and i don't know why :(
i need more information please
Re: [win32] - creating controls using class's
Quote:
Originally Posted by
Cambalinho
...
the label isn't created... and i don't know why :(
i need more information please
Then debug your code step-by-step to see what and where goes wrong.
And don't forget to call GetLastError after anyof the Windows API functions you are using has failed!
Re: [win32] - creating controls using class's
Quote:
Originally Posted by
VictorN
Then debug your code step-by-step to see what and where goes wrong.
And don't forget to call GetLastError after anyof the Windows API functions you are using has failed!
i tested with windows application and the label is showed.. great. now i must connect the label with a message loop:
SetWindowLong( GetParent(hwnd), GWL_WNDPROC,(LRESULT) WndProc);//the WndProc is the message loop
but seems that i mistake several things :(
can you advice me please?
Re: [win32] - creating controls using class's
Creating windows with a class of 'STATIC' etc doesn't require you to provide a 'wndproc' - these classes already have their own. You only need to do this with classes such as 'STATIC' if you are sub-classing the window. The third argument of SetWindowLong is of type LONG and not of type LRESULT. The first parameter is the handle of the window for which you want to change the value - and not its parent.
Re: [win32] - creating controls using class's
Quote:
Originally Posted by
2kaud
Creating windows with a class of 'STATIC' etc doesn't require you to provide a 'wndproc' - these classes already have their own. You only need to do this with classes such as 'STATIC' if you are sub-classing the window. The third argument of SetWindowLong is of type LONG and not of type LRESULT. The first parameter is the handle of the window for which you want to change the value - and not its parent.
i'm doing a class label control(with windows messages). so the window message loop must be inside the class... but i never used the these function for connect it with that procedure... please tell me more for i fix the problem :(
Re: [win32] - creating controls using class's
... and where's the message pump for the windows messages? Standard controls (such as static, edit etc) don't use message loops (unless you are sub-classing the control). If you are trying to create your own window, then you need to create and register a class and then create a window from this class. Windows programing assumes that things are done how they are expected to be done - and not how you might want to do them.
Re: [win32] - creating controls using class's
Quote:
Originally Posted by
2kaud
... and where's the message pump for the windows messages? Standard controls (such as static, edit etc) don't use message loops (unless you are sub-classing the control). If you are trying to create your own window, then you need to create and register a class and then create a window from this class. Windows programing assumes that things are done how they are expected to be done - and not how you might want to do them.
heres what i have now:
Code:
#include <windows.h>
#include <iostream>
#include <string>
using namespace std;
class label
{
private:
HWND hwnd;
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
SetWindowText(hwnd, "i'm alive");
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
public:
~label()
{
SetWindowLong(GetParent(hwnd), GWL_WNDPROC, 0);
}
label(HWND value)
{
hwnd = CreateWindowEx(
WS_EX_LEFT| WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR,
"STATIC",
"hello world",
SS_LEFT|WS_CHILD|WS_VISIBLE,
0, 0, 100, 100,
value,
NULL,
GetModuleHandle(NULL),
NULL);
SetWindowLongPtr(hwnd, GWL_WNDPROC, (LONG_PTR)WndProc);
ShowWindow(hwnd,SW_SHOW);
UpdateWindow(hwnd);
}
COORD GetSize()
{
RECT LabelSize;
GetWindowRect(hwnd,&LabelSize);
COORD crdSize={LabelSize.right-LabelSize.left,LabelSize.bottom-LabelSize.top};
return crdSize;
}
void SetText(string text)
{
char* chrText=(char*)text.c_str();
SetWindowText(hwnd, chrText);
}
};
Re: [win32] - creating controls using class's
ok... i could put the class regist and more, but the window procedure isn't activated :(
Code:
#include <windows.h>
#include <iostream>
#include <string>
using namespace std;
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_SHOWWINDOW:
SetWindowText(hwnd,"hello world!");
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
class label
{
private:
HWND hwnd;
const char* g_szClassName = "label";
WNDCLASSEX wc;
void RegistClass()
{
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = (HINSTANCE)GetModuleHandle(NULL);
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);
RegisterClassEx(&wc);
}
int do_events()
{
MSG Msg;
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
public:
~label()
{
SetWindowLong(GetParent(hwnd), GWL_WNDPROC, 0);
}
label(HWND value)
{
RegistClass();
hwnd = CreateWindowEx(
WS_EX_LEFT| WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR,
g_szClassName,
"hello world",
SS_LEFT|WS_CHILD|WS_VISIBLE,
0, 0, 100, 100,
value,
NULL,
GetModuleHandle(NULL),
NULL);
ShowWindow(hwnd,SW_SHOW);
UpdateWindow(hwnd);
do_events();
}
COORD GetSize()
{
RECT LabelSize;
GetWindowRect(hwnd,&LabelSize);
COORD crdSize={LabelSize.right-LabelSize.left,LabelSize.bottom-LabelSize.top};
return crdSize;
}
void SetText(string text)
{
char* chrText=(char*)text.c_str();
SetWindowText(hwnd, chrText);
}
};
what i'm doing wrong?
Re: [win32] - creating controls using class's
Quote:
Originally Posted by
Cambalinho
ok... i could put the class regist and more, but the window procedure isn't activated :(
Show us the main() program.
Quote:
what i'm doing wrong?
There isn't a single check for an error return value in your code that calls the Windows API. Why aren't you checking for return values?
Also, your GetMessage() loop should be written as described below:
http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx
Regards,
Paul McKenzie
Re: [win32] - creating controls using class's
Quote:
Originally Posted by
Cambalinho
i'm doing a class label control(with windows messages). so the window message loop must be inside the class...
What class? Control class never incorporates message pump. Message queue is owned by a thread, so there must be a single pump per thread servicing all the controls created in the context of the thread.
You're evidently lack of very basic knowledge of the way how window messages get processed in Windows, and trying to put this into OO paradigm makes the things be even worse.
Re: [win32] - creating controls using class's
I agree with Igor.
You shouldn't try and place an OO wrapper around the Windows API unless you know the Windows API. If you don't know how to put together a non-OO Win32 API program, then it makes absolutely no sense to try and place an object-oriented wrapper around the API.
This also applies to any API in general. To write object oriented wrappers around any API, whether it is Windows API, ODBC, TWAIN, etc. requires that you know, practically on an advanced level, the API you're trying to wrap.
Regards,
Paul McKenzie
Re: [win32] - creating controls using class's
Quote:
what i'm doing wrong?
Not understanding how basic Windows code works. The main() program (which is usually winmain() for a windows program) essentially consists of registering a windows class, creating the main window and then the message pump. Everything else is then done as part of wndproc() in response to messages received. There is only one message pump per thread - not one per c++ class/windows class. Trying to put an OO wrapper around the Windows API is non-trivial. Why do you want to do this? If you don't want to use Windows APIs directly, why not use readily available windows libraries or frameworks?
To get a feel for how to code for Windows API, have a read of
Programming Windows by Charles Petzold
http://www.amazon.co.uk/Programming-...harles+petzold
where it is explained how to put together windows programs. Then have a read of
Windows Via c/c++ by Jeffrey Richter
http://www.amazon.co.uk/Windows-Via-...ichter+windows
when you understand all of this, then you'll be in a position to produce an OO wrapper for the Windows API.
Why bother?
Re: [win32] - creating controls using class's
finally the message loop is used:
Code:
#include <windows.h>
#include <iostream>
#include <string>
#include <process.h>
using namespace std;
HWND hwnd;
HHOOK _hook;
WNDPROC previous_boring_subclassed_edit_proc;
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
MessageBox(NULL, "hi", "hello",MB_OK);
switch(msg)
{
case WM_MOUSEMOVE:
SetWindowText(hwnd,"hello");
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return CallWindowProc(previous_boring_subclassed_edit_proc, hwnd, msg, wParam, lParam);
}
return 0;
}
class label
{
private:
public:
label(HWND value)
{
hwnd = CreateWindowEx(
WS_EX_LEFT| WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR,
"STATIC",
"",
SS_LEFT|WS_CHILD|WS_VISIBLE,
0, 0, 100, 100,
value,
NULL,
GetModuleHandle(NULL),
NULL);
ShowWindow(hwnd,SW_SHOW);
UpdateWindow(hwnd);
previous_boring_subclassed_edit_proc = (WNDPROC)GetWindowLong(hwnd, GWL_WNDPROC);//get the default procedure
SetWindowLong(hwnd, GWL_WNDPROC, (LONG_PTR)WndProc);//set your custom procedure :)
}
COORD GetSize()
{
RECT LabelSize;
GetWindowRect(hwnd,&LabelSize);
COORD crdSize={LabelSize.right-LabelSize.left,LabelSize.bottom-LabelSize.top};
return crdSize;
}
void SetText(string text)
{
char* chrText=(char*)text.c_str();
SetWindowText(hwnd, chrText);
}
};
that message box is showed, so why the case isn't activated?
Re: [win32] - creating controls using class's
Quote:
that message box is showed, so why the case isn't activated?
The case is activated. It's just that its going to the default: section.
What is the value of msg? Have the MessageBox show msg and then you will see what messages you are receiving. They are defined in winuser.h .
For a control, you wouldn't normally process WM_CLOSE and WM_DESTROY.
Re: [win32] - creating controls using class's
Quote:
Originally Posted by
2kaud
The case is activated. It's just that its going to the default: section.
What is the value of msg? Have the MessageBox show msg and then you will see what messages you are receiving. They are defined in winuser.h .
For a control, you wouldn't normally process WM_CLOSE and WM_DESTROY.
maybe the case is activated, but the msg values are unexpected(the WM_CREATE isn't activated.. for example) :(