当表格STOPS被移动时,C#中是否有任何事件触发.不是在它移动的时候.
如果没有它的事件,有没有办法用WndProc做到这一点?
我有一个小问题希望有人会帮助我有没有办法挂钩到其他应用程序wndproc?
情况是我想在其他app菜单中插入菜单,我想为每个菜单项定义命令
我能够使用一些win32api函数(user32.dll)插入带有菜单项的菜单但是我无法设置该菜单项的命令,以便它实际上在点击时执行某些操作
通过一些谷歌搜索,我得到了一些关于wndprocess的信息,我应该拦截发送的ID命令并触发一些功能,但我卡住了.
谁能帮我?
我试图保持一个特定的WPF窗口焦点,这意味着它不应该在失去焦点时改变窗口样式(例如像标准的Windows任务栏).为了实现这一点,我钩到WndProc检查是否WM_NCACTIVATE或WM_ACTIVATE设置在假(wParam == 0),然后将消息标记为handled = true;从不活动块窗口.这是一些示例代码:
void Window_Loaded(object sender, RoutedEventArgs e)
{
var source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
if (source != null) source.AddHook(WndProc);
}
private const uint WM_NCACTIVATE = 0x0086;
private const int WM_ACTIVATE = 0x0006;
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == WM_NCACTIVATE)
{
if (wParam == new IntPtr(0))
handled = true;
}
if (msg == WM_ACTIVATE)
{
if (wParam == …Run Code Online (Sandbox Code Playgroud) 通常,当您打开模态对话框并尝试单击它的父窗口时,模态对话框的标题栏会闪烁.在WPF中创建自定义,无边框,无边框的窗口时,您将失去所有这些功能,并且必须自己重建它.我看起来又高又低,因为我的生活无法弄清楚如何让我的模态窗口闪烁.虽然它仍然会发出哔哔声......
我想我将不得不在WndProc中观察一些我必须处理的事件,但我无法弄清楚哪个事件或怎么做.我已经尝试观看窗口更改和窗口更改事件以及WM_ACTIVATE事件无济于事.我确定我只是错过了一些简单的东西,但我会很感激你的帮助.谢谢!
我正在一个IDE中创建一个hwnd及其各自的IDE WndProc LRESULT CALLBACK.我需要将其更改WndProc为自定义的.
我已经读过SetWindowLong会做的工作,但我找不到任何有效的例子.例如:
HWND hwnd; //My window
SetWindowLong(hwnd, GWL_WNDPROC, myNewWndProc);
第三个参数SetWindowLong是a Long作为函数名称的名称.如何从我的WndProc函数中引用Long?
我的WndProc:
LRESULT CALLBACK WndProcedure(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
msg_dev(toString(uMsg));
switch(uMsg){
case WM_MOUSEMOVE:
SetCursor(LoadCursor(NULL, IDC_HAND));
break;
case WM_LBUTTONDOWN:
msg_dev("Button down!");
break;
default:
DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
};
Run Code Online (Sandbox Code Playgroud) 如何在WPF中覆盖WndProc?当我的窗口关闭时,我尝试检查我正在使用的文件是否被修改,如果是这样,我必须向用户提示"你想保存更改吗?" 消息,然后关闭正在使用的文件和窗口.但是,当我的窗口仍然打开时,我无法处理用户重新启动/关闭/注销时的情况.我无法覆盖WndProc,因为我正在使用WPF进行开发.我也试过使用这个示例MSDN代码.这就是我所做的private void loadedForm(对象发送者,RoutedEventArgs e){
HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
source.AddHook(new HwndSourceHook(WndProc));
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == WM_QUERYENDSESION.)
{
OnWindowClose(this, new CancelEventArgs())
handled = true;
shutdown = true;
}
return IntPtr.Zero;
}
private void OnWindowClose(object sender, CancelEvetArgs e)
{
if (modified)
{
//show message box
//if result is yes/no
e.cancel = false;
//if cancel
e.cancel = true;
}
}
Run Code Online (Sandbox Code Playgroud)
在XAML文件上,我也使用Closing = "OnWindowClose"但是当我单击是/否时没有任何反应,我的应用程序没有关闭.如果我尝试使用关闭按钮再次关闭它,我收到一个错误?为什么会这样?是因为胡克?WPF中的等价物是什么?
private …Run Code Online (Sandbox Code Playgroud) 我有一个严重多线程的Delphi 6应用程序.我有一个我创建的组件,它来自TWinControl.当我第一次构建它时,我使用了一个隐藏窗口,它是WndProc来处理使用AllocateHwnd()分配的消息.最近我开始在我的代码中清理WndProc并决定删除辅助WndProc().我更改了组件以覆盖基类WndProc()方法,并从那里进行自定义窗口消息处理.在那个WndProc()中,我首先调用了继承的处理程序,然后处理了我的自定义消息(WM_USER偏移),如果找到我的一个自定义消息并将其处理,则将消息Result字段设置为1.
一个重要的说明.我在WndProc()覆盖的顶部放置了一行代码,如果当前线程id不是VCL主线程,则抛出异常.我想确保WndProc()仅在主VCL线程的上下文中执行.
在完成这个并运行我的程序后,我遇到了一些看起来很奇怪的东西.我正常运行我的程序并完成各种任务而没有错误.然后,当我转到与我的TWinControl后代位于同一页面的TMemo控件时.如果我在TMemo控件内部单击,则在我的WndProc()覆盖中触发主线程检查.我设置了断点,当我进入调用堆栈时,我的WndProc()覆盖上方没有任何内容.
据我所知,我已经仔细检查过,我没有明确调用WndProc()覆盖.那不是我做过的事.但鉴于我的TWinControl组件已经在主VCL线程上创建,就像所有其他组件一样,我无法理解WndProc()覆盖如何在后台线程的上下文中执行,尤其是在像UI这样的UI操作时鼠标点击会发生.我理解我的WndProc()是如何绑定到TMemo控件的,因为所有子窗口都挂在顶级窗口WndProc()上,至少这是我的理解.但由于所有组件窗口都是在主VCL线程上创建的,因此它们的所有消息队列也应该在该上下文中执行,对吧?
那么我可以创建什么样的情况来使我的WndProc()运行,有时只在后台线程的上下文中运行?
我有一个简单的窗口窗体,没有边框和几个标签控件(不需要单击任何内容)。我需要能够允许用户通过单击表单上的任意位置来移动表单,所以我找到了这个问题,并使用了在那里找到的以下代码。
private const int WM_NCHITTEST = 0x84;
private const int HTCLIENT = 0x1;
private const int HTCAPTION = 0x2;
protected override void WndProc(ref Message m)
{
switch (m.Msg) {
case WM_NCHITTEST:
base.WndProc(ref m);
if ((int)m.Result == HTCLIENT) {
m.Result = (IntPtr)HTCAPTION;
return;
} else {
return;
}
break;
}
base.WndProc(ref m);
}
Run Code Online (Sandbox Code Playgroud)
在某种程度上,这很有效。如果我单击表单本身(背景)上的任意位置,WM_NCHITTEST则为HTCLIENT,这样我就可以按预期移动表单。但是,如果我单击标签控件本身,则消息会有所不同,并且我无法分辨它是什么。
我发现这篇文章介绍了各种可能的值,WM_NCHITTEST但它们似乎都不是我需要的。
我意识到我可以禁用所有标签控件,这将允许我单击“它们”,就好像它是表单本身一样,但我想知道是否有更好/不同的方法来做到这一点。
谢谢您的帮助!
有人知道在调整大小事件结束时发送的消息吗(例如双击应用程序栏,单击最大化按钮,拖动到屏幕顶部,...),一个很好的例子是 WM_EXITSIZEMOVE,但它仅在窗口大小栏的拖动结束。
所以我的问题是,是否存在在发生任何调整大小事件时调用的消息,在它的末尾(不像 WM_SIZE)?
我在WPF项目中使用键盘挂钩成功地使用了条形码扫描仪,如下所示(我略过了一些细节,但是基本上,我可以依靠我知道哪个键盘是我的扫描仪的事实)。
/// <summary>
/// Add this KeyboardHook to a window
/// </summary>
/// <param name="window">The window to add to</param>
public void AddHook(Window window) {
if (form == null)
throw new ArgumentNullException("window");
if (mHwndSource != null)
throw new InvalidOperationException("Hook already present");
WindowInteropHelper w = new WindowInteropHelper(window);
IntPtr hwnd = w.Handle;
mHwndSource = HwndSource.FromHwnd(hwnd);
if (mHwndSource == null)
throw new ApplicationException("Failed to receive window source");
mHwndSource.AddHook(WndProc);
RAWINPUTDEVICE[] rid = new RAWINPUTDEVICE[1];
rid[0].usUsagePage = 0x01;
rid[0].usUsage = 0x06;
rid[0].dwFlags = RIDEV_INPUTSINK;
rid[0].hwndTarget = …Run Code Online (Sandbox Code Playgroud)