登録カスタムwin32窓からクラスc#
質問
私は新しいで書かれたアプリケーショコンポーネントのラインナップとニーズを支援古APIすることを可能にする受信メッセージが掲載されている隠れたウインドウです。通常は別のアプリケーションを使FindWindow特定の隠れたウィンドウの名前をカスタムウィンドウのクラスです。
1)これまでの想定を実施するカスタムウィンドウのクラスだと、男は高齢者らの自宅を訪れ学校win32電話?
私の古いc++アプリケーションを使用RegisterClass、警く最も簡単な見えないます。
と思っていき同じすべてのc#.ないで欲しいプロジェクトのメンバーが集合ポコードです。
しかしを継承す。Windowsの場合です。Interop.HwndHost用システム。を行います。InteropServices.DllImport引き上記のAPIです。
これまでの成功のホストを標準win32画面例"listbox"内のコンポーネントのラインナップ.しかし呼び出CreateWindowExのために私のカスタムウィンドウでは常にnullを返します。
私の話をRegisterClassが成功するものまでお問い合わせくださいけることができる設定を WNDCLASS.lpfnWndProc会員です。
2)は誰でも知っているこ順調に進んでいるのでしょうか?
解決
の記録だそして私はここです。切で、困った文字列に整列化です。私はこれまでに私の輸入のwin32ます。
以下のコードを作成する、カスタムウィンドウのクラスのクライアントまで、フルのc#-立支援のための古いApiいうカスタムウィンドウ。
この作業からコンポーネントのラインナップやポートとメッセージポンプが稼働してます。
編集:更新の報告衝突により早期回収を代のロッドやルアーを使用することをコールバック.に委譲され一員として代表の方が明示的に整列化機能としてポインタです。この修正の問題を容易に理解し、活動しています。
class CustomWindow : IDisposable
{
delegate IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
[System.Runtime.InteropServices.StructLayout(
System.Runtime.InteropServices.LayoutKind.Sequential,
CharSet = System.Runtime.InteropServices.CharSet.Unicode
)]
struct WNDCLASS
{
public uint style;
public IntPtr lpfnWndProc;
public int cbClsExtra;
public int cbWndExtra;
public IntPtr hInstance;
public IntPtr hIcon;
public IntPtr hCursor;
public IntPtr hbrBackground;
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
public string lpszMenuName;
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
public string lpszClassName;
}
[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
static extern System.UInt16 RegisterClassW(
[System.Runtime.InteropServices.In] ref WNDCLASS lpWndClass
);
[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
static extern IntPtr CreateWindowExW(
UInt32 dwExStyle,
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
string lpClassName,
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
string lpWindowName,
UInt32 dwStyle,
Int32 x,
Int32 y,
Int32 nWidth,
Int32 nHeight,
IntPtr hWndParent,
IntPtr hMenu,
IntPtr hInstance,
IntPtr lpParam
);
[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
static extern System.IntPtr DefWindowProcW(
IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam
);
[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
static extern bool DestroyWindow(
IntPtr hWnd
);
private const int ERROR_CLASS_ALREADY_EXISTS = 1410;
private bool m_disposed;
private IntPtr m_hwnd;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!m_disposed) {
if (disposing) {
// Dispose managed resources
}
// Dispose unmanaged resources
if (m_hwnd != IntPtr.Zero) {
DestroyWindow(m_hwnd);
m_hwnd = IntPtr.Zero;
}
}
}
public CustomWindow(string class_name){
if (class_name == null) throw new System.Exception("class_name is null");
if (class_name == String.Empty) throw new System.Exception("class_name is empty");
m_wnd_proc_delegate = CustomWndProc;
// Create WNDCLASS
WNDCLASS wind_class = new WNDCLASS();
wind_class.lpszClassName = class_name;
wind_class.lpfnWndProc = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate(m_wnd_proc_delegate);
UInt16 class_atom = RegisterClassW(ref wind_class);
int last_error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
if (class_atom == 0 && last_error != ERROR_CLASS_ALREADY_EXISTS) {
throw new System.Exception("Could not register window class");
}
// Create window
m_hwnd = CreateWindowExW(
0,
class_name,
String.Empty,
0,
0,
0,
0,
0,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero
);
}
private static IntPtr CustomWndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
{
return DefWindowProcW(hWnd, msg, wParam, lParam);
}
private WndProc m_wnd_proc_delegate;
}
他のヒント
んのコメントの答えはmorechilli:
public CustomWindow(string class_name){
if (class_name == null) throw new System.Exception("class_name is null");
if (class_name == String.Empty) throw new System.Exception("class_name is empty");
// Create WNDCLASS
WNDCLASS wind_class = new WNDCLASS();
wind_class.lpszClassName = class_name;
wind_class.lpfnWndProc = CustomWndProc;
UInt16 class_atom = RegisterClassW(ref wind_class);
int last_error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
if (class_atom == 0 && last_error != ERROR_CLASS_ALREADY_EXISTS) {
throw new System.Exception("Could not register window class");
}
// Create window
m_hwnd = CreateWindowExW(
0,
class_name,
String.Empty,
0,
0,
0,
0,
0,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero
);
}
コンストラクタにコピーしては若干の誤差:のWNDCLASSインスタンスが作成され、保存されません。では、いずれ必ずゴミを収集します。そのWNDCLASSのWndProcに限ります。この結果はエラーとWNDCLASSはゴミを収集します。インスタンスのWNDCLASSすべき有するメンバ変数までのウィンドウが破壊されました。
1) できるためサブクラスは通常のWindows Formsクラ---必要なすべての人びwin32電話する必要がありますが、すぐに解析をWndProcメッセージを手動で...ます。
2) インポートできます。Windowsの場合です。形名前空間を使ってコンポーネントのラインナップと共に、私はありませんので何の問題とんが絡くwindows formsおコンポーネントのラインナップ。だいたいインスタンスを生成するカスタム隠れた形receieveメッセージをそんなことがあったのですか。
例WndProcは、サブクラス:
protected override void WndProc(ref System.Windows.Forms.Message m)
{
// *always* let the base class process the message
base.WndProc(ref m);
const int WM_NCHITTEST = 0x84;
const int HTCAPTION = 2;
const int HTCLIENT = 1;
// if Windows is querying where the mouse is and the base form class said
// it's on the client area, let's cheat and say it's on the title bar instead
if ( m.Msg == WM_NCHITTEST && m.Result.ToInt32() == HTCLIENT )
m.Result = new IntPtr(HTCAPTION);
}
以降りますが、既にご存知のRegisterClassやWin32、こWndProcメッセージな問題のためにお---
WNDCLASS wind_class;の定義ではなく、クラスの機能や、クラッシュは固定式となります。