找到了可能的解决方案!
我相信我找到了解决方案!我将继续测试,以确保它确实工作,但我很有希望:)我已经详细说明了如何在EDIT三个问题中找到解决方案!
对于任何希望了解我的问题背后的完整背景以及由于此问题的输入而尝试过的人,请参阅:http://pastebin.com/nTrEAkVj
随着我的研究和情况的进展,我将经常对此进行编辑(大多数工作日每天> 3次),所以如果您有兴趣或者对我的问题有一些信息或了解,请继续检查:)
快速背景:
我有这个应用程序我可以通过更改我的屏幕保护程序或锁定我的工作站崩溃,并且通常每当发送WM_WININICHANGE/WM_SETTINGSCHANGE消息时.
如果我可以通过更改我的屏幕保护程序来持续崩溃我的应用程序,那么这样做的一部分就是向我的应用程序发送某种消息(不一定是Windows消息,我的意思是最普遍意义上的消息),这反过来对我来说是灾难性的应用.因此,我试图找到一种方法来阻止导致我的问题被我的应用程序处理的任何消息.我知道这不是解决方案的最佳方式,所以你不需要告诉我.查看背景信息或询问为什么会困扰您(有充分理由).
我的问题:
有几件事情,任何有关的信息都可以帮助我解决我的问题,根据相关性进行标记(1是最相关的,3稍微有点帮助):
我试图使用Wndproc()过滤掉我的消息,如下所示:
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If CInt(m.Msg) <> CInt(26) then
MyBase.WndProc(m)
end if
End Sub
Run Code Online (Sandbox Code Playgroud)
但是,根据Windspector,WM_WININICHANGE消息仍然被发送到我的应用程序(这是有道理的),但它也返回0 ...如果它正常工作不应该发生,它不应该返回什么,不应该吗?有关为什么这不符合我的预期以及如何使其工作的信息将非常有帮助!
我也尝试过使用messagefilters:
Public Class MyMessageFilter
Implements IMessageFilter
Public Function PreFilterMessage(ByRef m As Message) As Boolean Implements IMessageFilter.PreFilterMessage
' Return true for messages that you want to stop << someone elses comment
Return m.Msg = 26
End Function
End Class
Run Code Online (Sandbox Code Playgroud)
然后添加到mybase.load处理方法:
Application.AddMessageFilter(New MyMessageFilter())
然而,它们似乎只是过滤某些消息,而像我这样的消息显然没有被捕获.有关是否绝对无法使用任何类型的过滤器来捕获WM_消息的信息,或者是否有其他方法可以使用消息过滤器来实现我的目标也是有帮助的.
在其他方式(除了这个带有message.msg = WM_WININICHANGE = 26的Windows消息)我可以更改我的屏幕保护程序向我的应用程序发送任何类型的消息吗?更改我的屏幕保护程序的另一种消息是否也可能是致命的? …
我是Win32的新手,我一直在追求一个问题(如果它可以被称为问题),当用户抓住窗口标题栏并在屏幕上移动时,Windows会阻止程序的流程.
我没有合理的理由解决这个问题,除非它困扰我.一些可能性包括完全删除框架,但它似乎是一个不方便的黑客.有些游戏(单人游戏)根本没有发现这个问题.然而,我已经阅读过,当程序冻结时,多人游戏可能会遇到问题,因为它期望信息不断流动,并且在这样的延迟之后可能会被淹没.
我试过把它添加到我的 WindowProc
switch (uMsg)
{
case WM_SYSCOMMAND:
if (wParam == SC_CLOSE)
PostQuitMessage(0);
return 0;
...
...
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
Run Code Online (Sandbox Code Playgroud)
这似乎是一个快速的黑客,除了当我在关闭图标上徘徊时,我可以拉开鼠标并放开而不关闭程序,在此期间,当关闭图标时,程序再次被阻止.
此外,我不知道如何在用户单击标题栏并拖动鼠标时手动包含移动窗口所需的代码.对于初学者,我不知道要处理哪个uMsg和哪个wParam.
我的问题是,当用户点击退出按钮(或最小化/最大化按钮)时,如何在单击鼠标并通过按钮释放时处理案例时,如何禁止阻止,以及如何允许用户移动/拖动窗口而不阻止程序(或单击标题栏时发送的消息,而不是按钮或菜单)?
我正在创建窗口WS_SYSMENU | WS_MINIMIZEBOX.
我仍然希望程序响应最小化,最大化和退出命令.
如果多线程可以解决它,那么这很有趣,但我想知道我是否可以让它在单核处理器上工作.我已经阅读了有关钩子的内容,但MSDN页面仍然难以解释.
在delphi中,我可以像这样创建自己的消息,
const MY_MESSAGE = WM_USER+100;
procedure MyMessage(var Msg: TMessage); message MY_MESSAGE;
procedure TForm1.MyMessage(var Msg: TMessage);
begin
....
end;
Run Code Online (Sandbox Code Playgroud)
在c#中我可以这样做
public static uint ms;
protected override void WndProc(ref Message m)
{
if(m.Msg == ms)
MessageBox.Show("example");
else
base.WndProc(ref m);
}
void Button1Click(object sender, EventArgs e)
{
PostMessage(HWND_BROADCAST,ms,IntPtr.Zero,IntPtr.Zero);
}
Run Code Online (Sandbox Code Playgroud)
但是我不想覆盖WndProc(),我想创建自己的MyMessage()函数,当我发布消息时它会运行.
我怎样才能做到这一点?谢谢.
在查看Delphi源代码时,我经常会看到来自Windows API的消息声明,例如CN_NOTIFY和WM_NOTIFY.我想知道它们之间的差异以及何时应该使用它们?
我试图拦截来自另一个程序的鼠标点击.我正在为该程序制作一个插件,它在程序上覆盖透明表单并显示其他信息.当我单击表单的透明部分时,我可以单击main程序中的内容.我不希望这种情况发生(至少不是每次都发生 - 有些部分允许你点击,有些部分你不是,但这不是问题).
我现在这样做的方法是使用WH_MOUSE_LL,这工作正常,我可以通过返回非零值来保持鼠标点击进入程序(http://msdn.microsoft.com/en-gb/library /windows/desktop/ms644988(v=vs.85).aspx).
问题是,这使我的主程序滞后,我不需要获取所有鼠标移动的通知,我只想在用户实际点击某些内容时收到通知.有什么方法可以限制WH_MOUSE_LL它,所以只有鼠标点击才会触发吗?(滞后不是因为MouseHookProc方法中的计算- 它除了调用之外当前什么都不做CallNextHookEx(hHook, nCode, wParam, lParam).)
我试图通过使用挂钩消息的全局钩子(http://www.codeproject.com/Articles/18638/Using-Window-Messages-to-Implement-Global-System-H)来解决这个问题WM_MOUSEACTIVATE.我的想法只是WH_MOUSE_LL在收到WM_MOUSEACTIVATE通知时才挂钩.不幸的是WH_MOUSE_LL点击通知之前发送,WM_MOUSEACTIVATE所以这不起作用.
编辑:
@Nanda这里是proc代码:
public int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
return WindowUtility.CallNextHookEx(hHook, nCode, wParam, lParam);
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的那样,我对它没有做太多的事情,但它已经落后了......
@Cody Gray我对表单处理邮件做了一个非常小的测试:
public class Form1 : Form
{
private TrackBar m_Trackbar;
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
public Form1()
{
m_Trackbar …Run Code Online (Sandbox Code Playgroud) 我以前认为WM_CREATE是窗口收到的第一条消息.但是,在顶级窗口上测试此假设时,结果却是错误的.在我的测试中,WM_MINMAXINFO显示为第一条消息.
那么,窗口保证收到的第一条消息是什么?
我正在编写一个C#应用程序,它需要拦截另一个应用程序发出的Window Messages.编写我正在监控的应用程序的公司给我发了一些示例代码,但它是用C++编写的,我真的不知道.
在C++示例代码中,我得到了他们使用以下代码:
UINT uMsg = RegisterWindowMessage(SHOCK_MESSAGE_BROADCAST);
ON_REGISTERED_MESSAGE(WM_SHOCK_BROADCAST_MESSAGE, OnShockStatusMessage)
LRESULT OnShockStatusMessage(WPARAM wParam, LPARAM lParam);
Run Code Online (Sandbox Code Playgroud)
据我所知,这将从Windows中检索我们想要侦听的特定消息的Id.然后我们要求C++在拦截与Id匹配的消息时调用OnShockStatusMessage.
经过一番研究后,我在C#中整理了以下内容
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern uint RegisterWindowMessage(string lpString);
private IntPtr _hWnd; // APS-50 class reference
private List<IntPtr> _windowsMessages = new List<IntPtr>(); // APS-50 messages
private const string _className = "www.AuPix.com/SHOCK/MessageWindowClass";
// Windows Messages events
private const string _messageBroadcast = "www.AuPix.com/SHOCK/BROADCAST";
private const string _messageCallEvents …Run Code Online (Sandbox Code Playgroud) 我正在研究需要监控多种形式的东西.从表单外部,并且不在表单中放置任何代码,我需要以某种方式从这些表单中捕获事件,最有可能以Windows消息的形式.但是你如何捕获与它相关的类外的Windows消息呢?
我的项目有一个对象,它包装它正在监视的每个表单,我认为这个处理将进入这个对象.基本上,当我创建一个我想要监视的表单时,我创建了一个相应的对象,该对象又被添加到所有已创建表单的列表中.最重要的是,当该表单关闭时,我必须知道所以我可以从列表中删除此表单的包装器对象.
这些活动包括:
我不想要的:
OnClose因为它们将用于其他目的我想要的是:
问题用相同的信息重写,但方法不同
在Windows 7中,备忘录控件(TMemo)将在文本被插入(Memo.Lines.Add(Path);)之后自动滚动,这是我不想要的,因为滚动是由我自己完成的.
如何停止自动滚动?
我在这里的示例项目工作:http://www.codeproject.com/Articles/8086/Extending-the-save-file-dialog-class-in-NET
我已经将地址/位置栏隐藏在顶部并进行了其他修改,但我不能在我的生活中设法禁用允许您转到父文件夹的按钮.Ist在ToolbarWindow32类中就是问题所在.这就是我现在所拥有的,但它不起作用:
int parentFolderWindow = GetDlgItem(parent, 0x440);
//Doesn't work
//ShowWindow((IntPtr)parentFolderWindow, SW_HIDE);
//40961 gathered from Spy++ watching messages when clicking on the control
// doesn't work
//SendMessage(parentFolderWindow, TB_ENABLEBUTTON, 40961, 0);
// doesn't work
//SendMessage(parentFolderWindow, TB_SETSTATE, 40961, 0);
//Comes back as '{static}', am I working with the wrong control maybe?
GetClassName((IntPtr)parentFolderWindow, lpClassName, (int)nLength);
Run Code Online (Sandbox Code Playgroud)
或者,如果他们确实使用父文件夹按钮并且去了我不想要的地方,我可以查看他们登陆的新目录,有没有办法可以强制导航返回?

编辑:添加截图
windows-messages ×10
c# ×4
delphi ×4
winapi ×4
.net ×3
c++ ×2
c ×1
delphi-7 ×1
delphi-xe3 ×1
hook ×1
messages ×1
mfc ×1
ofnhookproc ×1
tform ×1
vb.net ×1