子类化 子类化的本质是通过 SetWindowLong 传入 GWL_WNDPROC 参数。 <WndProc>(OnWndProc); _originalWndProc = SetWindowLongPtr(hWnd, GWL_WNDPROC, wndProc); IntPtr OnWndProc = OnWndProc; var wndProc = Marshal.GetFunctionPointerForDelegate<WndProc>(_wndProc); _originalWndProc = SetWindowLongPtr(hWnd, GWL_WNDPROC, wndProc); } private WndProc _wndProc; SetWindowLongPtr(hWnd, GWL_WNDPROC, _originalWndProc); 上面需要的所有的 P/Invoke 我都贴到了下面,需要的话放到你的代码当中。
SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As LongPrivate Const GWL_WNDPROC Private Const WM_CONTEXTMENU = &H7B '-------------右键菜单Private prevWndProc As LongPrivate Function WndProc WM_COPY, WM_PASTE, WM_CLEAR, EM_UNDO, WM_CONTEXTMENU '这里处理自定义的事件,最好为空 Case Else '回调系统函数处理 WndProc DisableAbility(TargetTextBox As TextBox) '程序启动时调用这个 prevWndProc = GetWindowLong(TargetTextBox.hwnd, GWL_WNDPROC ) SetWindowLong TargetTextBox.hwnd, GWL_WNDPROC, AddressOf WndProcEnd Sub
dwNewLong As Long) As LongPrivate Const EM_GETRECT = &HB2Private Const EM_SETRECTNP = &HB4Private Const GWL_WNDPROC ) SetWindowLong TargetTextBox.hwnd, GWL_WNDPROC, AddressOf WndProcEnd SubPrivate Function WndProc(ByVal lParam As Long) As Long Dim Temp As String Select Case Msg Case WM_CHAR If wParam <> 13 Then WndProc , Chr(10), "") Temp = Replace(Temp, Chr(13), "") Clipboard.Clear Clipboard.SetText Temp WndProc prevWndProc, hwnd, Msg, wParam, lParam) Clipboard.Clear Clipboard.SetText ClipText Case Else WndProc
答案是肯定的,它就是 WndProc 函数。所有的消息都要经过这个函数处理。 Windows 程序有两种消息,一种是队列消息,它通过 DispatchMessage 函数分发给 WndProc 函数,像鼠标消息、键盘消息,Timer消息都是这类消息。 另一种是非队列消息,它是系统函数直接发送给 WndProc 函数的,像窗口的创建与消毁消息,WM_COMMON消息等等都是非队列消息。 () 上面一节我也介绍了 WndProc 是 Windows 程序的消息中心。 它说 WndProc 就是 WndProc,它说 WindowProc 就是 WindowProc。
WndProc 在.NET框架类库中的System.Windows.Forms命名空间中微软采用面对对象的方式重新定义了Message。 protected override void WndProc(ref System.Windows.Forms.Message e); 对于每个Form来说,我们都可以重写该方法,该方法的参数就是上面提到的 ,所以如果希望底层能处理相关的消息,需要通过base.WndProc传递到父类继续调用。 下面就是一个代码示例来展示控制如果当前的消息是鼠标左键点击,则弹出MessageBox展示“WndProc MouseClick”: protected override void WndProc(ref MouseClick"); return; } base.WndProc(ref m); } IMessageFilter 除了上述的WndProc之外,其实更加便于处理应该的实现
语法如下: typedef struct tagWNDCLASSEXA { UINT cbSize; UINT style; WNDPROC lpfnWndProc; 在微软的文档中写道:“WndProc 是每个 Windows 桌面应用程序必须的窗口过程功能。 此函数通常命名为WndProc,但您可以随心所欲地命名它。 例如,如果用户在应用程序中选择"确定"按钮,Windows 会向您发送消息,您可以在WndProc函数内编写代码,执行任何适当的操作。 这称为处理事件。 您只处理与应用程序相关的事件。 WndProc 具有以下语法”;如下:。 LRESULT CALLBACK WndProc( _In_ HWND hWnd, _In_ UINT message, _In_ WPARAM wParam, _In_
代码如下: #region 去掉Flash右键菜单,API函数的声明 private const int GWL_WNDPROC = -4; public delegate CharSet.Auto)] public static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, FlaWndProc wndProc DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr CallWindowProc(IntPtr wndProc this.Wpr = new FlaWndProc(this.FlashWndProc); this.OldWndProc = SetWindowLong(Myflash.Handle, GWL_WNDPROC (ref Message m) //重载WndProc方法(此方法即消息处理机制) { if (m.Msg == 0X0204) //0×0204即鼠标右键的
Charles Petzold, 1998 ---------------------------------------*/ #include <windows.h> LRESULT CALLBACK WndProc wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } LRESULT CALLBACK WndProc Charles Petzold, 1998 ----------------------------------------*/ #include <windows.h> LRESULT CALLBACK WndProc wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc
WndProc // // 摘要: // 处理 Windows 消息。 protected override void WndProc(ref System.Windows.Forms.Message e); 对于每个Form来说,我们都可以重写该方法,该方法的参数就是上面提到的 ,所以如果希望底层能处理相关的消息,需要通过base.WndProc传递到父类继续调用。 下面就是一个代码示例来展示控制如果当前的消息是鼠标左键点击,则弹出MessageBox展示“WndProc MouseClick”: protected override void WndProc(ref MouseClick"); return; } base.WndProc(ref m); } IMessageFilter 除了上述的WndProc之外,其实更加便于处理应该的实现
代码如下: #include<windows.h> #include<stdlib.h> #include<string.h> long WINAPI WndProc ( HWND hWnd, UINT TranslateMessage(&Message); DispatchMessage(&Message); } return Message.wParam; } long WINAPI WndProc ; WndClass.hIcon = LoadIcon(NULL, "END"); WndClass.hInstance = hInstance; WndClass.lpfnWndProc = WndProc ; WndClass.hIcon = LoadIcon(NULL, "END"); WndClass.hInstance = hInstance; WndClass.lpfnWndProc = WndProc
= new WNDCLASS { lpszClassName = className }; _wndProc = CustomWndProc; windClass.lpfnWndProc = Marshal.GetFunctionPointerForDelegate(_wndProc MarshalAs(UnmanagedType.LPWStr)] public string lpszClassName; } private delegate IntPtr WndProc (IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); private readonly WndProc _wndProc;
你看看能不能帮我改一下 #include #include #define PI 3.14 int cxClient, cyClient ; float i, j, x, y ; LRESULT CALLBACK WndProc msg ; WNDCLASS wndclass; HWND hwnd ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc= WndProc 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } LRESULT CALLBACK WndProc
---------------------------------*/ #include <windows.h> #define ID_TIMER 1 LRESULT CALLBACK WndProc wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } LRESULT CALLBACK WndProc
到论坛求助后才得到前辈指点:"这种嵌入控件的控件,最好用wndproc回调函数处理消息。 否则应在父控件窗口中转发命令消息。" 第一种方法:用wndproc回调函数处理消息 import win.ui; /*DSG{{*/ var winform = ..win.form( bottom=356;parent=... right=50;bottom=206;autoResize=false ;hide=1;edge=1;hide=0;text="btn4";id=103; }; ) winform.listview.wndproc autoResize=false ;edge=1; oncommand=function(id,event){ io.print("1111") } } ) winform.listview.wndproc 1,2,,2) winform.listview.edit.setRect(rc) winform.show() win.loopMessage(); 相关知识:WM_COMMAND(窗口消息) wndproc
static LRESULT mSpinBox_wndProc (mSpinBox* self, UINT message, WPARAM wParam, LPARAM lParam) { switch , 0); break; } default: break; } return Class(mSpinner).wndProc ((mSpinner*)self, message, wParam, lParam); } 知道原因就有了解决办法 解决方案1 修改libmgncs-1.2.0的源码,修改上面的mSpinBox_wndProc return TRUE; } } } return FALSE; } static LRESULT mSpinBox_wndProc return FALSE; } default: break; } return Class(mSpinner).wndProc
TranslateMessage(CONST MSG *lpMsg); 分发消息 LRESULT DispatchMessage(CONST MSG *lpMsg); 六.回调函数 LRESULT CALLBACK WndProc (//WndProc名称自定义 HWND hwnd,//窗口句柄 UINTmessage,//消息ID WPARAM wParam, LPARAM lParam)//两个消息参数 LRESULT CALLBACK WndProc(HWND hwnd,UINTmessage,WPARAM wParam,LPARAM lParam) {//让系统自动处理默认消息 return DefWindowProc(hwnd ,message,wParam,lParam); } wc.lpfnWndProc = WndProc;//回调函数 可将代码和解析结合看
ptr [esp+0x4], pThis (esp+0x4 is hWnd) DWORD m_this; // BYTE m_jmp; // jmp WndProc pThis->m_thunk.Init(WindowProc, pThis); WNDPROC pProc = pThis->m_thunk.GetWNDPROC(); WNDPROC pOldProc = (WNDPROC)::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)pProc); #ifdef _DEBUG
三、窗口与消息 3.1.HELLOWIN程序 main.c #pragma comment(lib, "winmm") #include <windows.h> LRESULT CALLBACK WndProc HWND hwnd; MSG msg; WNDCLASS wndclass; //水平尺寸和垂直尺寸 wndclass.style = CS_HREDRAW | CS_VREDRAW; //WndProc 翻译一些键盘消息 DispatchMessage(&msg); //将消息发送给窗口过程 } return msg.wParam; } //窗口过程函数 LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK ListProc(HWND, UINT, WPARAM, LPARAM); WNDPROC OldList , szAppName, MB_YESNO | MB_ICONQUESTION); } LRESULT CALLBACK WndProc(HWND hwnd, UINT message
include "stdafx.h" #include "peekmessage.h" #include <Windows.h> #include <stdlib.h> LRESULT CALLBACK WndProc WNDCLASS wcex; wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc FillRect(hdc,&rect,hBrush); ReleaseDC(hWnd,hdc); DeleteObject(hBrush); } LRESULT CALLBACK WndProc
WND_POS_X 100 #define WND_POS_Y 100 #define WND_WIDTH 500 #define WND_HEIGHT 600 //声明 LRESULT CALLBACK WndProc 窗口左上角的图标 wc.hIconSm = NULL;//状态栏中的图标,默认与左上角图标一致 wc.hInstance = hInstance;//实例句柄 wc.lpfnWndProc = WndProc 0, 0)) { //翻译消息 TranslateMessage(&mSg); //分发消息 DispatchMessage(&mSg); } } LRESULT CALLBACK WndProc