Window message without creating a form?  
Author Message
Tom B





PostPosted: Visual C# General, Window message without creating a form? Top

Hello,

Do I need to create a form just so I can have a handle I want my application to listen to window messages but it actually has no forms.
It seems a bit wasteful to create a form just to listen for window messages, cant I give my entire application a WndProc function

I'd like to use the bare minimum resources to do this. The form will have nothing on it so I think the best way would just be to use CreateWindow() but I'm not sure what else I need to use this, or how to create a WndProc function for it.

Is there any basic code examples for creating a window using purley the API



Visual C#20  
 
 
shieldy





PostPosted: Visual C# General, Window message without creating a form? Top

I'm not sure I have understand your means fully:

you can create a window to listen the message with API( c):

eg:

#include <windows.h>

HWND hwnd;

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
char szClassName[] = "MidTest";
WNDCLASSEX wndclass;
wndclass.cbSize = sizeof(wndclass); // 构的大小
wndclass.style = CS_HREDRAW|CS_VREDRAW; // 指定如果大小改 就重
wndclass.lpfnWndProc = MainWndProc; // windows process function( you can write a process to deal with the message
wndclass.cbClsExtra = 0; // 有 外的 存
wndclass.cbWndExtra = 0; // 有 外的窗口 存
wndclass.hInstance = hInstance; // 例句柄
wndclass.hIcon = ::LoadIcon(hInstance,
(LPSTR)IDI_ICON); // 使用 定
wndclass.hCursor = ::LoadCursor(hInstance,
(LPSTR)IDC_CURSOR1); // 使用 定 的光
wndclass.hbrBackground = (HBRUSH)
::GetStockObject(WHITE_BRUSH); // 使用白色背景 刷
wndclass.lpszMenuName = (LPSTR)IDR_MENU1; // 不指定菜
wndclass.lpszClassName = szClassName ; // 窗口 的名
wndclass.hIconSm = NULL; // 有 的小
::RegisterClassEx(&wndclass);// 注 窗口
// 建主窗口
hwnd = ::CreateWindowEx(
0, // dwExStyle, 展 式
szClassName, // lpClassName, 名
"MidTest", // lpWindowName,
WS_OVERLAPPEDWINDOW, // dwStyle,窗口 格
CW_USEDEFAULT, // X,初始 X 坐
CW_USEDEFAULT, // Y,初始 Y 坐
CW_USEDEFAULT, // nWidth, 度
CW_USEDEFAULT, // nHeight,高度
NULL, // hWndParent,父窗口句柄
NULL, // hMenu,菜 句柄
hInstance, // hlnstance,程序 例句柄
NULL) ; // lpParam,用 据

if(hwnd == NULL)
{
::MessageBox(NULL, "window error", "error", MB_OK);
return -1;
}
::ShowWindow(hwnd, nCmdShow);
::UpdateWindow(hwnd);
MSG msg;
while(::GetMessage(&msg, NULL, 0, 0))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
return msg.wParam;
}

but I only know the C source, as I'm new to c#. maybe your'll get some ideas.



 
 
Tom B





PostPosted: Visual C# General, Window message without creating a form? Top

Yeah, i've done this in Delphi Before.

I need to create a WndClass structure but i'm not sure how. I can call CreateWindowEx (Why should I use this instead of CreateWindow ) but without the WndClass structure it's pretty useless.

I found a post on experts-exchange (http://www.experts-exchange.com/Programming/Programming_Languages/C_Sharp/Q_21063912.html) which says this is the way to define the structure:

[DllImport("user32.dll")]
public static extern int RegisterClass(ref WNDCLASS wndcls);

But when I try to use it, it gives me the error that WNDCLASS cannot be found.

 
 
Tom B





PostPosted: Visual C# General, Window message without creating a form? Top

Ok, I found all the structures I need at pinvoke.net

Why doesnt this work




IntPtr hInst = Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly().GetModule("Program.exe"));
MSG msg;
WNDCLASS wClass = new WNDCLASS();
wClass.lpszClassName = "test";
wClass.lpfnWndProc = new WndProc(WProc);
wClass.hInstance = hInst;
wClass.hbrBackground = (IntPtr)1;

RegisterClass(ref wClass);

IntPtr wnd = CreateWindowEx(0, wClass.lpszClassName, "Test", WS_VISIBLE + WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, IntPtr.Zero, IntPtr.Zero, hInst, IntPtr.Zero);

ShowWindow(wnd, 5);


while (GetMessage(out msg, IntPtr.Zero, 0, 0)) {
DispatchMessage(ref msg);
}

 
 
Tech Stylist





PostPosted: Visual C# General, Window message without creating a form? Top

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]

public struct WNDCLASSEXW

{

public uint cbSize;

public int style;

public WNDPROC lpfnWndProc;

public int cbClsExtra;

public int cbWndExtra;

public IntPtr hInstance;

public IntPtr hIcon;

public IntPtr hCursor;

public IntPtr hbrBackground;

public string lpszMenuName;

public string lpszClassName;

public IntPtr hIconSm;

}

/// <summary>

/// This is the delegate for a windows procedure

/// </summary>

public delegate int WNDPROC(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);

// Create an instance of the window class structure

fWndClass = new WNDCLASSEXW();

// Somewhere in the class that's doing all this, you should have a function

// called Callback that should look appropriate.

fWindowProc = new WNDPROC(this.Callback);

IntPtr fAppInstance = Kernel32.GetModuleHandle(null);

// Fill in the structure with all the interesting stuff

fWndClass.cbSize = (uint)Marshal.SizeOf(typeof(WNDCLASSEXW));

fWndClass.style = CS_HREDRAW | CS_VREDRAW; // Pick appropriate style flags

fWndClass.lpfnWndProc = fWindowProc;

fWndClass.cbClsExtra = 0; // Not asking for any extra storage space right now

fWndClass.cbWndExtra = 0; // Not asking for extra storage space

fWndClass.hInstance = Kernel32.GetModuleHandle(null);

fWndClass.hIcon = IntPtr.Zero;

fWndClass.hCursor = IntPtr.Zero;

fWndClass.hbrBackground = (IntPtr)(COLOR_WINDOW + 1);

fWndClass.lpszMenuName = null;

fWndClass.lpszClassName = "mywindowclassname";

fWndClass.hIconSm = IntPtr.Zero;

fClassAtom = User32.RegisterClassExW(ref fWndClass);

// Now that the class is registered, you're ready to actually create a window

IntPtr fHandle = IntPtr.Zero;

fHandle = User32.CreateWindowEx(

exStyle, // Look for a windowless style

"mywindowclassname", // Needs to be the same as what you registered

"Title of Window",

WS_OVERLAPPEDWINDOW, // Look for a windowless style

10,

10,

320,

240,

IntPtr.Zero, // No Parent

IntPtr.Zero,

fAppInstance,

0);

public int Callback(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)

{

MSG m = MSG.Create(hWnd, msg, wParam, lParam);

IntPtr result;

// Do what should be done by default if we don't handle it specifically

result = User32.DefWindowProc(hWnd, msg, wParam, lParam);

return result.ToInt32();

}

That's pretty much it. You still need to implement a message dispatch look somewhere:

While (GetMessage(ref myMSG))

{

TranslateMessage(myMSG);

DispatchMessage(myMSG);

}

But that's about it. Look in the styles and extra styles enums for something related to windowless windows and you'll get a message queue with no window at all, which I think is what you wanted originally.


 
 
IsshouFuuraibou





PostPosted: Visual C# General, Window message without creating a form? Top

One thing to note is that the form itself is not what causes the message queue to be pumped, it's the call to Application.Run that starts up the message queue processing.

Application.Run() has an overload that allows you to start the message queue without a form.

I however do not know what you'll need to do to get the message queue processed.
Application.Run overloads
Application Methods

AddMessageFilter and RegisterMessageLoop look promising. AddMessageFilter looks like what you'd most likely use, make sure to add the filters before calling Application.Run() as that is a blocking operation.


 
 
Peter Ritchie





PostPosted: Visual C# General, Window message without creating a form? Top

One thing to note is that the form itself is not what causes the message queue to be pumped, it's the call to Application.Run that starts up the message queue processing.

Application.Run() has an overload that allows you to start the message queue without a form.

I however do not know what you'll need to do to get the message queue processed.
Application.Run overloads
Application Methods

AddMessageFilter and RegisterMessageLoop look promising. AddMessageFilter looks like what you'd most likely use, make sure to add the filters before calling Application.Run() as that is a blocking operation.
Application.Run just implements something like:

While (GetMessage(ref myMSG))

{

TranslateMessage(myMSG);

DispatchMessage(myMSG);

}