Trying to specify the native windows class to be used underneath of my custom winform with get_Creat

B

Bern McCarty

I am trying to figure out how to create a windows form such that the
underlying native window is of a custom windows class of my choosing. This
should allow me to, among other things, specify that I want some extra space
in the window so that I can use SetWindowLongPtr/GetWindowLongPtr on the
underlying HWND. I have some native code that I'm hoping to leverage that
wants to use GetWindowLongPtr() on the window.

Firstly, is this feasible? The documentation seems to imply that it is. It
would stand to reason that there might be some constraints on you when
trying to do this but there are none spelled out anywhere that I can see. I
get the following run-time error when trying to create my winform:

An unhandled exception of type 'System.ComponentModel.Win32Exception'
occurred in system.windows.forms.dll

Additional information: Invalid window class name.

Am I supposed to NOT pass the name of an already registered windows class?
I ask because NativeWindow.WindowClass.RegisterClass() appears in my stack
at the time of the exception:
win32Intface_winMainStartFromForeignExecutable(void* hInst = 0x00400000,
void* hPrevInst = <undefined value>, char* programName = <undefined value>,
char* cmdLineP = 0x00251f1d, __int32 cmdShow = 0x5, void* exitFunc =
<undefined value>) Line 20747 C++
System.Windows.Forms.NativeWindow.WindowClass.RegisterClass() + 0x2c2
bytes
System.Windows.Forms.NativeWindow.WindowClass.WindowClass(string className
= "MStnChild", int classStyle = 0x8) + 0x28 bytes
System.Windows.Forms.NativeWindow.WindowClass.Create(string className =
"MStnChild", int classStyle = 0x8) + 0xfe bytes

System.Windows.Forms.NativeWindow.CreateHandle(System.Windows.Forms.CreatePa
rams cp = {System.Windows.Forms.CreateParams}) + 0x108 bytes
System.Windows.Forms.Control.CreateHandle() + 0x1bb bytes
System.Windows.Forms.Form.CreateHandle() + 0x15d bytes
System.Windows.Forms.Control.get_Handle() + 0x34 bytes
Bentley.Mstn.Nonport.WinForms.BaseWinForm.BaseWinForm(mswindow*
__unnamed000 = 0x10fb0c60, System.Windows.Forms.CreateParams __unnamed001 =
0x0022c068) Line 59 + 0xa bytes C++

Yet, when I don't register the window class I get:

An unhandled exception of type 'System.ComponentModel.Win32Exception'
occurred in system.windows.forms.dll

Additional information: Invalid window class name.

If using custom windows classes underneath a winform is feasible, does
anyone have an sample code showing how to do it right?
 
Y

Ying-Shen Yu[MSFT]

Hi Bern,

From your description, I suspect the problem might be caused by the .NET
couldn't find the corresponding ClassName, by default
CreateParams.ClassName is null and NativeWindow class will register a new
window class automatically, when the ClassName is not null,
NativeWindow.WindowClass RegisterClass method will try to retrieve the
class by API GetClassInfo, and subclass the window proc.

I suspect both exception in your post is caused by GetClassInfo failed to
retrieve the class by name, I'd like you check if the API you called is
RegisterClassW/RegisterClassExW (unicode version), Or you may just set your
app charset to unicode charset and try again.

If the problem persists, could you post some code snippets (the code to
register wndclass, the code in get_CreateParams function) in the reply,
maybe we can find come clue from it.
Thanks!

Best regards,

Ying-Shen Yu [MSFT]
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security

This posting is provided "AS IS" with no warranties and confers no rights.
This mail should not be replied directly, "online" should be removed before
sending.
 
B

Bern McCarty

Ying-Shen Yu,

I checked and it is RegisterClassA that we're using. Here is the
preprocessed code:

subClass.style = 0x0020;
subClass.lpfnWndProc = win32Intface_childWindowProc;
subClass.cbClsExtra = 0;
subClass.cbWndExtra = sizeof(GuiWindowP) + sizeof(INT_PTR);
subClass.hInstance = w32G.instance;
subClass.hIcon = LoadIconA (subClass.hInstance,
(LPSTR)((ULONG_PTR)((WORD)(2))));
subClass.hCursor = 0;
subClass.hbrBackground = 0;
subClass.lpszMenuName = 0;
subClass.lpszClassName = "MStnChild";
RegisterClassA (&subClass);

This is a big app, and I'm not clear on the implications of changing its
Windows to Unicode. Short of that, do you have any other ideas? I gather
you suspect that .NET isn't handling ANSI windows classes properly?

-Bern
 
B

Bern McCarty

I forgot to include the code for my override of the CreateParams property.
I have no idea if this is the right way to do this. Not shown is that the
"createParamsP" member of my winform get's set in the class' constructor
initializer list. As I recall, I added the test for NULL when I found that
get_CreateParams was being called prior to the constructor initializer list
being run (much to my surprise).
namespace WForms=System::Windows::Forms;

WForms::CreateParams* BaseWinForm::get_CreateParams
(
)
{
WForms::CreateParams *baseCPP = this->WForms::Form::get_CreateParams();

if (NULL == this->createParamsP)
return baseCPP;

baseCPP->set_Caption(this->createParamsP->get_Caption());

System::String *winFormClassName =
System::String::Concat(this->createParamsP->get_ClassName(), S"WinForm");
baseCPP->set_ClassName (winFormClassName);

baseCPP->set_ExStyle(this->createParamsP->get_ExStyle());
baseCPP->set_Style(this->createParamsP->get_Style());
baseCPP->set_Parent(this->createParamsP->get_Parent());

return baseCPP;
}


Bern McCarty said:
Ying-Shen Yu,

I checked and it is RegisterClassA that we're using. Here is the
preprocessed code:

subClass.style = 0x0020;
subClass.lpfnWndProc = win32Intface_childWindowProc;
subClass.cbClsExtra = 0;
subClass.cbWndExtra = sizeof(GuiWindowP) + sizeof(INT_PTR);
subClass.hInstance = w32G.instance;
subClass.hIcon = LoadIconA (subClass.hInstance,
(LPSTR)((ULONG_PTR)((WORD)(2))));
subClass.hCursor = 0;
subClass.hbrBackground = 0;
subClass.lpszMenuName = 0;
subClass.lpszClassName = "MStnChild";
RegisterClassA (&subClass);

This is a big app, and I'm not clear on the implications of changing its
Windows to Unicode. Short of that, do you have any other ideas? I gather
you suspect that .NET isn't handling ANSI windows classes properly?

-Bern

"Ying-Shen Yu[MSFT]" said:
Hi Bern,

From your description, I suspect the problem might be caused by the .NET
couldn't find the corresponding ClassName, by default
CreateParams.ClassName is null and NativeWindow class will register a new
window class automatically, when the ClassName is not null,
NativeWindow.WindowClass RegisterClass method will try to retrieve the
class by API GetClassInfo, and subclass the window proc.

I suspect both exception in your post is caused by GetClassInfo failed to
retrieve the class by name, I'd like you check if the API you called is
RegisterClassW/RegisterClassExW (unicode version), Or you may just set your
app charset to unicode charset and try again.

If the problem persists, could you post some code snippets (the code to
register wndclass, the code in get_CreateParams function) in the reply,
maybe we can find come clue from it.
Thanks!

Best regards,

Ying-Shen Yu [MSFT]
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security

This posting is provided "AS IS" with no warranties and confers no rights.
This mail should not be replied directly, "online" should be removed before
sending.
 
Y

Ying-Shen Yu[MSFT]

Hi Bern,

After further research, I found winform control will not use the
application local window class, it internally uses GetClassInfo with first
argument set to NULL,
And the document on CreateParams.ClassName said:
To derive from an existing control class, store the system class name in
this property.
Here the system class name is refer to System global window class which is
provided by Windows System and could not be added/removed.
For more information on Window class, you may refer to

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwui/html/
msdn_classy32.asp

I think you need modify the related code and use a instance variable of
your Form class instead.

Thanks!


Best regards,

Ying-Shen Yu [MSFT]
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security

This posting is provided "AS IS" with no warranties and confers no rights.
This mail should not be replied directly, "online" should be removed before
sending.
 
Y

Ying-Shen Yu[MSFT]

Hi,
Forget to mention,
the property CreateParams is used in the constructor of Control class,
which was the base class of Form and executed prior to Form constructor.

Thanks!

Best regards,

Ying-Shen Yu [MSFT]
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security

This posting is provided "AS IS" with no warranties and confers no rights.
This mail should not be replied directly, "online" should be removed before
sending.
 
Top