H
Hashka
Hello everyone.
I have a big problem in my C# code for my Smart device project
(IPAQ/pocketpc 2003)
I am trying to apply the MSDN "Asynchronous callbacks from native
Win32 code" sample to my own case and I do not managed to make it work
as I want.
I have a GUI C# application that use a native DLL function (ReplyMe),
called thanks to P/Invoke interop feature of .NET.
This native function only sends a window message to the handle of the
window that called it, and waits for 5 seconds before returning true.
My C# application has its own MessageWindow object, with the WndProc
method overiden.
The C# application pass the handle of the MessageWindow to the native
function
in order to enable it to use SendMessage function with the approprate
handle as parameter.
All is working pretty great except the fact that the WndProc method of
my own MessageWindow is never triggered, and never catch any message.
The native function is called correctly, is processed correctly (waits
the correct time), and retuns the correct value (true boolean).
However it seems that the message sent is not received on the managed
C# side.
I am really out of resources.
I copy my whole code in order to let you take a look to it if you have
the will.
I describe a bit what i am giving to you
*** Form1.cs: The C# basic form, it has an attribute of type
JoMessageWindow in order to collect the windows messages
*** JoMessageWindo.cs: My own MessageWindow class, with an attribute
of type Form1 in order to modify some GUI attributes of the Form.
I have overriden the WndProc method in order to
deal the message as i want.
The problem is that i never go through the
WndProc method code
*** LibWrap.cs: This is the helper classe that enable to call my
native function
*** JoDll.h and JoDll.cpp: the source code of my native DLL
The C# was compiled thanks to Visual Studio .NET 2003
the DLL was compiled thanks to EVC4.0 sp2
I would really appreciate any help
Thanks again for reading this long long post
/************
* Form1.cs *
************/
using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Data;
using Microsoft.WindowsCE.Forms;
namespace tescs
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button Identify;
public System.Windows.Forms.Label info_msg;
//
// I reference my own MessageWindow
//
private JoWindowMessage m__msgWnd;
public Form1()
{
InitializeComponent();
//
// I construct own MessageWindow with the handle of the current form
//
m__msgWnd = new JoWindowMessage(this);
}
protected override void Dispose( bool disposing )
{
base.Dispose( disposing );
}
private void InitializeComponent()
{
this.Identify = new System.Windows.Forms.Button();
this.info_msg = new System.Windows.Forms.Label();
this.Identify.Location = new System.Drawing.Point(80, 112);
this.Identify.Text = "Identify";
this.Identify.Click += new
System.EventHandler(this.Identify_Click);
this.info_msg.Location = new System.Drawing.Point(56, 40);
this.info_msg.Size = new System.Drawing.Size(128, 40);
this.info_msg.Text = "Click on the button";
this.info_msg.TextAlign =
System.Drawing.ContentAlignment.TopCenter;
this.Controls.Add(this.info_msg);
this.Controls.Add(this.Identify);
this.Text = "Form1";
}
static void Main()
{
Application.Run(new Form1());
}
private void Identify_Click(object sender, System.EventArgs e)
{
//
// I call here the helper fonction of my native DLL. I give the handle
of my own MessageWindow handle
//
bool ret = LibWrap.ReplyMe(m__msgWnd.Hwnd);
if(ret)
info_msg.Text = "Identified";
else
info_msg.Text = "Not identified";
}
public void DisplayInfoCB (string item)
{
info_msg.Text = item;
}
}
}
/**********************
* JoWindowMessage.cs *
**********************/
using System;
using Microsoft.WindowsCE.Forms;
using System.Windows.Forms;
namespace tescs
{
//
// This is my own MessageWindow. This is a classic MessageWindow with
a reference on a Form
//
public class JoWindowMessage:MessageWindow
{
private const int WM_USER = 0x400;
private const int WM_ASYNCDATA_RECEIVED = WM_USER + 1;
private Form1 destinationForm;
public JoWindowMessage(Form1 destinationForm)
{
this.destinationForm = destinationForm;
}
//
// This is the override of the WndProc. HERE IS THE PROBLEM, WE NEVER
COME IN THIS METHOD
//
protected override void WndProc(ref Message msg)
{
switch(msg.Msg)
{
case WM_ASYNCDATA_RECEIVED:
unsafe
{
string str = new string((char *)msg.LParam.ToPointer());
destinationForm.DisplayInfoCB(str);
break;
}
}
// call the base class WndProc for default message handling
base.WndProc(ref msg);
}
}
}
/**************
* LibWrap.cs *
**************/
using System;
using System.Runtime.InteropServices;
namespace tescs
{
public class LibWrap
{
[DllImport("JoDll.dll")]
public static extern bool ReplyMe(IntPtr hWnd);
}
}
/***********
* JoDll.h *
***********/
#ifdef JODLL_EXPORTS
#define JODLL_API __declspec(dllexport)
#else
#define JODLL_API __declspec(dllimport)
#endif
#define WM_ASYNCDATA_RECEIVED WM_USER+1
extern "C" JODLL_API bool ReplyMe(HWND hWnd);
/*************
* JoDll.cpp *
*************/
#include "stdafx.h"
#include "Joll.h"
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
//
// This is my native function called from the managed side.
//It just sends a message to the handle provided (that is the
MessageWindow),
//and wait for 5 seconds
//
JODLL_API bool ReplyMe(HWND hWnd)
{
SendMessage(hWnd), WM_ASYNCDATA_RECEIVED, 0, NULL);
Sleep(5000);
return true;
}
I have a big problem in my C# code for my Smart device project
(IPAQ/pocketpc 2003)
I am trying to apply the MSDN "Asynchronous callbacks from native
Win32 code" sample to my own case and I do not managed to make it work
as I want.
I have a GUI C# application that use a native DLL function (ReplyMe),
called thanks to P/Invoke interop feature of .NET.
This native function only sends a window message to the handle of the
window that called it, and waits for 5 seconds before returning true.
My C# application has its own MessageWindow object, with the WndProc
method overiden.
The C# application pass the handle of the MessageWindow to the native
function
in order to enable it to use SendMessage function with the approprate
handle as parameter.
All is working pretty great except the fact that the WndProc method of
my own MessageWindow is never triggered, and never catch any message.
The native function is called correctly, is processed correctly (waits
the correct time), and retuns the correct value (true boolean).
However it seems that the message sent is not received on the managed
C# side.
I am really out of resources.
I copy my whole code in order to let you take a look to it if you have
the will.
I describe a bit what i am giving to you
*** Form1.cs: The C# basic form, it has an attribute of type
JoMessageWindow in order to collect the windows messages
*** JoMessageWindo.cs: My own MessageWindow class, with an attribute
of type Form1 in order to modify some GUI attributes of the Form.
I have overriden the WndProc method in order to
deal the message as i want.
The problem is that i never go through the
WndProc method code
*** LibWrap.cs: This is the helper classe that enable to call my
native function
*** JoDll.h and JoDll.cpp: the source code of my native DLL
The C# was compiled thanks to Visual Studio .NET 2003
the DLL was compiled thanks to EVC4.0 sp2
I would really appreciate any help
Thanks again for reading this long long post
/************
* Form1.cs *
************/
using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Data;
using Microsoft.WindowsCE.Forms;
namespace tescs
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button Identify;
public System.Windows.Forms.Label info_msg;
//
// I reference my own MessageWindow
//
private JoWindowMessage m__msgWnd;
public Form1()
{
InitializeComponent();
//
// I construct own MessageWindow with the handle of the current form
//
m__msgWnd = new JoWindowMessage(this);
}
protected override void Dispose( bool disposing )
{
base.Dispose( disposing );
}
private void InitializeComponent()
{
this.Identify = new System.Windows.Forms.Button();
this.info_msg = new System.Windows.Forms.Label();
this.Identify.Location = new System.Drawing.Point(80, 112);
this.Identify.Text = "Identify";
this.Identify.Click += new
System.EventHandler(this.Identify_Click);
this.info_msg.Location = new System.Drawing.Point(56, 40);
this.info_msg.Size = new System.Drawing.Size(128, 40);
this.info_msg.Text = "Click on the button";
this.info_msg.TextAlign =
System.Drawing.ContentAlignment.TopCenter;
this.Controls.Add(this.info_msg);
this.Controls.Add(this.Identify);
this.Text = "Form1";
}
static void Main()
{
Application.Run(new Form1());
}
private void Identify_Click(object sender, System.EventArgs e)
{
//
// I call here the helper fonction of my native DLL. I give the handle
of my own MessageWindow handle
//
bool ret = LibWrap.ReplyMe(m__msgWnd.Hwnd);
if(ret)
info_msg.Text = "Identified";
else
info_msg.Text = "Not identified";
}
public void DisplayInfoCB (string item)
{
info_msg.Text = item;
}
}
}
/**********************
* JoWindowMessage.cs *
**********************/
using System;
using Microsoft.WindowsCE.Forms;
using System.Windows.Forms;
namespace tescs
{
//
// This is my own MessageWindow. This is a classic MessageWindow with
a reference on a Form
//
public class JoWindowMessage:MessageWindow
{
private const int WM_USER = 0x400;
private const int WM_ASYNCDATA_RECEIVED = WM_USER + 1;
private Form1 destinationForm;
public JoWindowMessage(Form1 destinationForm)
{
this.destinationForm = destinationForm;
}
//
// This is the override of the WndProc. HERE IS THE PROBLEM, WE NEVER
COME IN THIS METHOD
//
protected override void WndProc(ref Message msg)
{
switch(msg.Msg)
{
case WM_ASYNCDATA_RECEIVED:
unsafe
{
string str = new string((char *)msg.LParam.ToPointer());
destinationForm.DisplayInfoCB(str);
break;
}
}
// call the base class WndProc for default message handling
base.WndProc(ref msg);
}
}
}
/**************
* LibWrap.cs *
**************/
using System;
using System.Runtime.InteropServices;
namespace tescs
{
public class LibWrap
{
[DllImport("JoDll.dll")]
public static extern bool ReplyMe(IntPtr hWnd);
}
}
/***********
* JoDll.h *
***********/
#ifdef JODLL_EXPORTS
#define JODLL_API __declspec(dllexport)
#else
#define JODLL_API __declspec(dllimport)
#endif
#define WM_ASYNCDATA_RECEIVED WM_USER+1
extern "C" JODLL_API bool ReplyMe(HWND hWnd);
/*************
* JoDll.cpp *
*************/
#include "stdafx.h"
#include "Joll.h"
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
//
// This is my native function called from the managed side.
//It just sends a message to the handle provided (that is the
MessageWindow),
//and wait for 5 seconds
//
JODLL_API bool ReplyMe(HWND hWnd)
{
SendMessage(hWnd), WM_ASYNCDATA_RECEIVED, 0, NULL);
Sleep(5000);
return true;
}