Re: [win32] - creating controls using class's
Code:
void setparent(HWND parent)
{
static int i=i+1;
string strclass=labelclassprop + to_string(i);
labelclassprop=strclass.c_str();
WNDCLASS wc;
HINSTANCE mod = (HINSTANCE)GetModuleHandle(NULL);
ZeroMemory(&wc, sizeof(WNDCLASS));
GetClassInfo(mod, "STATIC", &wc);
wc.hInstance = mod;
wc.lpszClassName = labelclassprop;
wc.hbrBackground = CreateSolidBrush(RGB(255,0,0));
// store the old WNDPROC of the EDIT window class
// store the old WNDPROC of the EDIT window class
SetProp(parent, labelpropname, (HANDLE)wc.lpfnWndProc);
//SetProp(parent, labelclassprop, (HANDLE)this);
//UpdateWindow(hwnd);
// replace it with local WNDPROC
wc.lpfnWndProc = WndProc;
// register the new window class, "ShEdit"
if (!RegisterClass(&wc))
MessageBox(NULL, "error in register", "error", MB_OK);
hwnd = CreateWindowEx(
WS_EX_LEFT| WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_TRANSPARENT,
labelclassprop,
labelclassprop,
SS_LEFT|WS_CHILD|WS_VISIBLE|WS_OVERLAPPED,
100, 100, 100, 100,
parent,
NULL,
mod,
(LPVOID)this);
if (hwnd == NULL)
MessageBox(NULL, "error in create", "error", MB_OK);
//SetProp(parent, labelpropname, (HANDLE)wc.lpfnWndProc);
SetProp(hwnd, labelclassprop, (HANDLE)this);
UpdateWindow(hwnd);
}
Re: [win32] - creating controls using class's
sorry, but i must go back...
see these code:
Code:
void setparent(HWND parent)
{
static int i=i+1;
string strclass=labelclassprop + to_string(i);
caption=(string)"Label " + to_string(i);
labelclassprop=strclass.c_str();
WNDCLASS wc;
HINSTANCE mod = (HINSTANCE)GetModuleHandle(NULL);
i have 1 problem, the i isn't incremented.
if it's static, it should be incremented, but maybe because i'm using it in a diferent instance, isn't incremented.
(after fix these, i will show you 1 thing with my code)
Re: [win32] - creating controls using class's
No. This doesn't do what you expect. Effectively this statement is only executed once for the first time setparent() is called. Subsequently it is not executed.
You need something like this
Code:
static int i = 0;
i++;
This can be shown using a simple test program.
Code:
#include <iostream>
using namespace std;
int inc()
{
static int i = i +1;
return i;
}
int main()
{
for (int k = 0; k < 10; k++)
cout << inc() << " ";
cout << endl;
return 0;
}
This produces the output
Code:
1 1 1 1 1 1 1 1 1 1
whereas
Code:
#include <iostream>
using namespace std;
int inc()
{
static int i = 0;
i = i + 1;
return i;
}
int main()
{
for (int k = 0; k < 10; k++)
cout << inc() << " ";
cout << endl;
return 0;
}
produces the output
Code:
1 2 3 4 5 6 7 8 9 10
Re: [win32] - creating controls using class's
Quote:
Originally Posted by
2kaud
No. This doesn't do what you expect. Effectively this statement is only executed once for the first time setparent() is called. Subsequently it is not executed.
You need something like this
Code:
static int i = 0;
i++;
This can be shown using a simple test program.
Code:
#include <iostream>
using namespace std;
int inc()
{
static int i = i +1;
return i;
}
int main()
{
for (int k = 0; k < 10; k++)
cout << inc() << " ";
cout << endl;
return 0;
}
This produces the output
Code:
1 1 1 1 1 1 1 1 1 1
whereas
Code:
#include <iostream>
using namespace std;
int inc()
{
static int i = 0;
i = i + 1;
return i;
}
int main()
{
for (int k = 0; k < 10; k++)
cout << inc() << " ";
cout << endl;
return 0;
}
produces the output
Code:
1 2 3 4 5 6 7 8 9 10
thanks for correct me
1 Attachment(s)
Re: [win32] - creating controls using class's
now see these:
Code:
void setparent(HWND parent)
{
static int i = 0;
i++;
string strclass=labelclassprop + to_string(i);
caption=(string)"Label " + to_string(i);
labelclassprop=strclass.c_str();
WNDCLASS wc;
HINSTANCE mod = (HINSTANCE)GetModuleHandle(NULL);
ZeroMemory(&wc, sizeof(WNDCLASS));
GetClassInfo(mod, "STATIC", &wc);
wc.hInstance = mod;
wc.lpszClassName = labelclassprop;
wc.hbrBackground = CreateSolidBrush(RGB(255,0,0));
// store the old WNDPROC of the EDIT window class
SetProp(parent, labelpropname, (HANDLE)wc.lpfnWndProc);
SetProp(parent, labelclassprop, (HANDLE)this);
// replace it with local WNDPROC
wc.lpfnWndProc = WndProc;
// register the new window class, "ShEdit"
if (!RegisterClass(&wc))
MessageBox(NULL, "error in register", "error", MB_OK);
hwnd = CreateWindowEx(
WS_EX_LEFT| WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_TRANSPARENT,
labelclassprop,
caption.c_str(),
SS_LEFT|WS_CHILD|WS_VISIBLE|WS_OVERLAPPED,
100, 100, 100, 100,
parent,
NULL,
mod,
(LPVOID)this);
if (hwnd == NULL)
MessageBox(NULL, "error in create", "error", MB_OK);
UpdateWindow(hwnd);
}
if i regist all class's(number of class's = number of windows = number of instances), why i get the wrong hwnd:
Code:
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
WNDPROC oldproc = (WNDPROC)GetProp(GetParent(hwnd), labelpropname);
label *inst = (label*)GetProp(GetParent(hwnd), labelclassprop);
if (oldproc == NULL || inst == NULL)
MessageBox(NULL, "null", "null", MB_OK);
????
why, i belive, it's wrong??? because if i move the mouse in label 1 the window procedure works, but with hwn of label 2, because changes everything in label 2.
see the image anexed
Re: [win32] - creating controls using class's
As I explained in a previous post, it's because you are setting the labelclassproperty that contains the class inst pointer for the label parent rather than the label window itself. See my code in posts #120 and #121 for possible changes to WndPric and SetParent. So every label window gets the same class inst. So the class inst has to be set for the label window. However, the WM_CREATE message is sent before the property is set. So the class inst needs to be passed to WM_CREATE via the CREATESTRUCT. So if the label control property is not available and the message is WM_CREATE then the class inst can be picked up via the lParam pointer to the CREATESTRUCT.
Code:
void setparent(HWND parent)
{
static int i = 0;
i++;
string strclass=labelclassprop + to_string(i);
labelclassprop=strclass.c_str();
WNDCLASS wc;
HINSTANCE mod = (HINSTANCE)GetModuleHandle(NULL);
ZeroMemory(&wc, sizeof(WNDCLASS));
GetClassInfo(mod, "STATIC", &wc);
wc.hInstance = mod;
wc.lpszClassName = labelclassprop;
wc.hbrBackground = CreateSolidBrush(RGB(255,0,0));
// store the old WNDPROC of the EDIT window class
SetProp(parent, labelpropname, (HANDLE)wc.lpfnWndProc);
// replace it with local WNDPROC
wc.lpfnWndProc = WndProc;
// register the new window class, "ShEdit"
if (!RegisterClass(&wc))
MessageBox(NULL, "error in register", "error", MB_OK);
hwnd = CreateWindowEx(
WS_EX_LEFT| WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_TRANSPARENT,
labelclassprop,
labelclassprop,
SS_LEFT|WS_CHILD|WS_VISIBLE|WS_OVERLAPPED,
100, 100, 100, 100,
parent,
NULL,
mod,
(LPVOID)this);
if (hwnd == NULL)
MessageBox(NULL, "error in create", "error", MB_OK);
SetProp(hwnd, labelclassprop, (HANDLE)this);
UpdateWindow(hwnd);
}
Code:
WNDPROC oldproc = (WNDPROC)GetProp(GetParent(hwnd), labelpropname);
if (oldproc == NULL)
MessageBox(NULL, "oldprocnull", "oldprocnull", MB_OK);
label *inst = (label*)GetProp(hwnd), labelclassprop);
if (inst == NULL && msg == WM_CREATE)
inst = (label*)(((LPCREATESTRUCT)lParam)->lpCreateParams);
if (inst == NULL)
MessageBox(NULL, "instnull, "instnull", MB_OK);
Re: [win32] - creating controls using class's
Quote:
Originally Posted by
2kaud
As I explained in a previous post, it's because you are setting the labelclassproperty that contains the class inst pointer for the label parent rather than the label window itself. See my code in posts #120 and #121 for possible changes to WndPric and SetParent. So every label window gets the same class inst. So the class inst has to be set for the label window. However, the WM_CREATE message is sent before the property is set. So the class inst needs to be passed to WM_CREATE via the CREATESTRUCT. So if the label control property is not available and the message is WM_CREATE then the class inst can be picked up via the lParam pointer to the CREATESTRUCT.
Code:
void setparent(HWND parent)
{
static int i = 0;
i++;
string strclass=labelclassprop + to_string(i);
labelclassprop=strclass.c_str();
WNDCLASS wc;
HINSTANCE mod = (HINSTANCE)GetModuleHandle(NULL);
ZeroMemory(&wc, sizeof(WNDCLASS));
GetClassInfo(mod, "STATIC", &wc);
wc.hInstance = mod;
wc.lpszClassName = labelclassprop;
wc.hbrBackground = CreateSolidBrush(RGB(255,0,0));
// store the old WNDPROC of the EDIT window class
SetProp(parent, labelpropname, (HANDLE)wc.lpfnWndProc);
// replace it with local WNDPROC
wc.lpfnWndProc = WndProc;
// register the new window class, "ShEdit"
if (!RegisterClass(&wc))
MessageBox(NULL, "error in register", "error", MB_OK);
hwnd = CreateWindowEx(
WS_EX_LEFT| WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_TRANSPARENT,
labelclassprop,
labelclassprop,
SS_LEFT|WS_CHILD|WS_VISIBLE|WS_OVERLAPPED,
100, 100, 100, 100,
parent,
NULL,
mod,
(LPVOID)this);
if (hwnd == NULL)
MessageBox(NULL, "error in create", "error", MB_OK);
SetProp(hwnd, labelclassprop, (HANDLE)this);
UpdateWindow(hwnd);
}
Code:
WNDPROC oldproc = (WNDPROC)GetProp(GetParent(hwnd), labelpropname);
if (oldproc == NULL)
MessageBox(NULL, "oldprocnull", "oldprocnull", MB_OK);
label *inst = (label*)GetProp(hwnd), labelclassprop);
if (inst == NULL && msg == WM_CREATE)
inst = (label*)(((LPCREATESTRUCT)lParam)->lpCreateParams);
if (inst == NULL)
MessageBox(NULL, "instnull, "instnull", MB_OK);
sorry the inst is NULL
Re: [win32] - creating controls using class's
let me ask: why i can't use 'this' inside of window procedure?
Re: [win32] - creating controls using class's
Quote:
Originally Posted by
Cambalinho
let me ask: why i can't use 'this' inside of window procedure?
Because WndProc is static and static functions can't access 'this'. WndProc has to be static due to the way it is used.
Quote:
sorry the inst is NULL
For which message?
Re: [win32] - creating controls using class's
Quote:
Originally Posted by
2kaud
Because WndProc is static and static functions can't access 'this'. WndProc has to be static due to the way it is used.
For which message?
before the case
if (inst == NULL)
MessageBox(NULL, "instnull", "instnull", MB_OK);
Re: [win32] - creating controls using class's
Quote:
Originally Posted by
Cambalinho
let me ask: why i can't use 'this' inside of window procedure?
The Windows API is 'C' based. A window procedure has no idea about the C++ language. Therefore, there is no such thing as "this", objects, etc. in the Windows API.
Regards,
Paul McKenzie
Re: [win32] - creating controls using class's
The sequence of messages sent when a control window is created is
WM_NCCREATE
WM_NCCALCSIZE
WM_CREATE
WM_SIZE
WM_MOVE
WM_SHOWWINDOW
For the first 2 of these, inst will certainly be NULL but doesn't matter as you are not processing these messages.
Try changing
Code:
if (inst == NULL)
MessageBox(NULL, "instnull, "instnull", MB_OK);
to
Code:
if ((inst == NULL) && (msg != WM_NCCREATE && msg != WM_NCCALCSIZE)
MessageBox(NULL, "instnull"m "instnull", MB_OK);
If this still says that inst is null, show the value of msg in the messagebox.
Re: [win32] - creating controls using class's
Quote:
Originally Posted by
2kaud
The sequence of messages sent when a control window is created is
WM_NCCREATE
WM_NCCALCSIZE
WM_CREATE
WM_SIZE
WM_MOVE
WM_SHOWWINDOW
For the first 2 of these, inst will certainly be NULL but doesn't matter as you are not processing these messages.
Try changing
Code:
if (inst == NULL)
MessageBox(NULL, "instnull, "instnull", MB_OK);
to
Code:
if ((inst == NULL) && (msg != WM_NCCREATE && msg != WM_NCCALCSIZE)
MessageBox(NULL, "instnull"m "instnull", MB_OK);
If this still says that inst is null, show the value of msg in the messagebox.
sorry the same error and the windows close my application :(
Re: [win32] - creating controls using class's
Nasty! There are several messages sent after WM_CREATE but before the property has been set.
Change
Code:
WNDPROC oldproc = (WNDPROC)GetProp(GetParent(hwnd), labelpropname);
if (oldproc == NULL)
MessageBox(NULL, "oldprocnull", "oldprocnull", MB_OK);
label *inst = (label*)GetProp(hwnd), labelclassprop);
if (inst == NULL && msg == WM_CREATE)
inst = (label*)(((LPCREATESTRUCT)lParam)->lpCreateParams);
if (inst == NULL)
MessageBox(NULL, "instnull, "instnull", MB_OK);
to
Code:
WNDPROC oldproc = (WNDPROC)GetProp(GetParent(hwnd), labelpropname);
if (oldproc == NULL)
MessageBox(NULL, "oldprocnull", "oldprocnull", MB_OK);
label *inst = (label*)GetProp(hwnd, labelclassprop);
if (inst == NULL && msg == WM_NCCREATE){
inst = (label*)(((LPCREATESTRUCT)lParam)->lpCreateParams);
SetProp(hwnd, labelclassprop, (HANDLE)inst);
}
if (inst == NULL)
MessageBox(NULL, "instnull", "instnull", MB_OK);
This now works on my test version.
Re: [win32] - creating controls using class's
Quote:
Originally Posted by
2kaud
Nasty! There are several messages sent after WM_CREATE but before the property has been set.
Change
Code:
WNDPROC oldproc = (WNDPROC)GetProp(GetParent(hwnd), labelpropname);
if (oldproc == NULL)
MessageBox(NULL, "oldprocnull", "oldprocnull", MB_OK);
label *inst = (label*)GetProp(hwnd), labelclassprop);
if (inst == NULL && msg == WM_CREATE)
inst = (label*)(((LPCREATESTRUCT)lParam)->lpCreateParams);
if (inst == NULL)
MessageBox(NULL, "instnull, "instnull", MB_OK);
to
Code:
WNDPROC oldproc = (WNDPROC)GetProp(GetParent(hwnd), labelpropname);
if (oldproc == NULL)
MessageBox(NULL, "oldprocnull", "oldprocnull", MB_OK);
label *inst = (label*)GetProp(hwnd, labelclassprop);
if (inst == NULL && msg == WM_NCCREATE){
inst = (label*)(((LPCREATESTRUCT)lParam)->lpCreateParams);
SetProp(hwnd, labelclassprop, (HANDLE)inst);
}
if (inst == NULL)
MessageBox(NULL, "instnull", "instnull", MB_OK);
This now works on my test version.
no :(
or i miss something from you, or i don't know :(
Code:
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
WNDPROC oldproc = (WNDPROC)GetProp(GetParent(hwnd), labelpropname);
if (oldproc == NULL)
MessageBox(NULL, "oldprocnull", "oldprocnull", MB_OK);
label *inst = (label*)GetProp(hwnd, labelclassprop);
if (inst == NULL && msg == WM_NCCREATE)
{
inst = (label*)(((LPCREATESTRUCT)lParam)->lpCreateParams);
SetProp(hwnd, labelclassprop, (HANDLE)inst);
}
if (inst == NULL)
MessageBox(NULL, "instnull", "instnull", MB_OK);
static bool TrackingMouse = false;
static bool WindowStopMoving = NULL;
static bool WindowStopResize = NULL;
static const UINT_PTR MouseStopTimerID = 1;
HBRUSH g_hbrBackground = CreateSolidBrush(NULL_BRUSH);
switch(msg)
{
case WM_CTLCOLORSTATIC:
{
HDC hdcStatic = (HDC)wParam;
SetTextColor(hdcStatic, inst->clrTextColor);
SetBkMode(hdcStatic, TRANSPARENT);
SetBkColor(hdcStatic,inst->clrBackColor);
g_hbrBackground = CreateSolidBrush(inst->clrBackColor);
return (LONG)g_hbrBackground;
}
break;
case WM_CREATE:
{
static int xPos = (int)(short) LOWORD(lParam);
static int yPos = (int)(short) HIWORD(lParam);
inst->Create(xPos,yPos);
}
break;
...................................................................................
void setparent(HWND parent)
{
static int i = 0;
i++;
string strclass=labelclassprop + to_string(i);
labelclassprop=strclass.c_str();
WNDCLASS wc;
HINSTANCE mod = (HINSTANCE)GetModuleHandle(NULL);
ZeroMemory(&wc, sizeof(WNDCLASS));
GetClassInfo(mod, "STATIC", &wc);
wc.hInstance = mod;
wc.lpszClassName = labelclassprop;
wc.hbrBackground = CreateSolidBrush(RGB(255,0,0));
// store the old WNDPROC of the EDIT window class
SetProp(parent, labelpropname, (HANDLE)wc.lpfnWndProc);
// replace it with local WNDPROC
wc.lpfnWndProc = WndProc;
// register the new window class, "ShEdit"
if (!RegisterClass(&wc))
MessageBox(NULL, "error in register", "error", MB_OK);
hwnd = CreateWindowEx(
WS_EX_LEFT| WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_TRANSPARENT,
labelclassprop,
labelclassprop,
SS_LEFT|WS_CHILD|WS_VISIBLE|WS_OVERLAPPED,
100, 100, 100, 100,
parent,
NULL,
mod,
(LPVOID)this);
if (hwnd == NULL)
MessageBox(NULL, "error in create", "error", MB_OK);
SetProp(hwnd, labelclassprop, (HANDLE)this);
UpdateWindow(hwnd);
clrBackColor=GetPixel(GetDC(hwnd),0,0);
}
sorry if i bored you with these, but it's new for me :(