我有一个双重问题,我对它的两个分支都不熟悉。
背景 我从MSI购买了一台新笔记本电脑。作为我以前从未见过的功能,CD驱动器没有安装在驱动器上的机械弹出按钮。相反,数字弹出按钮是功能键上方“智能条”的一部分。不幸的是,智能条下面的软件非常糟糕。即使在被动模式下它占用了屏幕空间和它占用了任务栏上的空间。*我已经卸载了这个软件。
项目: 我想编写一个在启动时运行的程序,并且在后台不显眼。该程序的唯一功能是使弹出按钮弹出CD驱动器。
第一步:我想知道当我按下按钮时会发生什么。我怀疑我不需要编码任何东西,但可以使用实用程序 - 我的一位同事提到了“事件记录器”,但谷歌提供了无用的东西。
第二步:我想编写所说的程序,这意味着我需要与WIN32或可能的.net框架进行交互,以便在我右键单击“我的电脑”下的CD驱动器时执行调用Windows所使用的相同函数然后单击“弹出”。
问题: 第一个问题:你知道一个实用工具会告诉我按下按钮会发生什么吗?
第二个问题:你知道我需要在该事件上调用哪个函数来弹出驱动器吗?
第三个问题:我是否忽略了一些明显的其他道路?
我对“我遇到同样的问题,这是我写的解决方案的源代码”中的任何答案持开放态度“我想也许这个教程可以帮到你吗?”
我更喜欢使用C / C ++ / C#,但我愿意接受其他建议。正如标题所述,我在Windows 7下工作。
*好奇的是,该软件是MSI S-Bar,由于某种原因被吹捧为这一系列笔记本电脑的“功能”。
答案 0 :(得分:1)
<强>热键强>
如果它们是键盘的一部分(仅仅因为它们看起来像是,它们并不意味着它们确实存在),它们将具有扫描码。 SetWindowsHookEx可用于查找扫描码,并对其作出反应 - 以下代码应该有所帮助:
class Program
{
static void Main(string[] args)
{
var myClass = new MyClass();
myClass.Install();
Application.Run(new Form()); // You need a form, not sure why.
myClass.Uninstall();
}
}
public class MyClass : CriticalFinalizerObject
{
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(HookType idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("winmm.dll")]
static extern Int32 mciSendString(String command, StringBuilder buffer, Int32 bufferSize, IntPtr hwndCallback);
private delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
private enum HookType : int
{
WH_KEYBOARD = 2,
WH_KEYBOARD_LL = 13
}
private enum WindowsMessage : int
{
WM_KEYUP = 0x101
}
private HookProc _myCallbackDelegate;
private IntPtr _hook;
public MyClass()
{
_myCallbackDelegate = MyCallbackFunction;
}
public void Install()
{
Uninstall();
using (Process process = Process.GetCurrentProcess())
using (ProcessModule module = process.MainModule)
{
_hook = SetWindowsHookEx(HookType.WH_KEYBOARD_LL, _myCallbackDelegate, GetModuleHandle(module.ModuleName), 0);
}
}
public void Uninstall()
{
var ptr = Interlocked.Exchange(ref _hook, IntPtr.Zero);
if (ptr != IntPtr.Zero)
UnhookWindowsHookEx(ptr);
}
private IntPtr MyCallbackFunction(int code, IntPtr wParam, IntPtr lParam)
{
if (code >= 0 && wParam == (IntPtr)WindowsMessage.WM_KEYUP)
{
var sk = Marshal.ReadInt32(lParam);
// This can be used to find the scancode.
// Press the key and watch the console to find out the scancode.
Console.WriteLine("ScanCode: 0x{0:x4}", sk);
if (sk == 0x0041) // 0x0041 is A
{
// We can't hold up the hook for too long; start the
// tray open on another thread.
new Action(OpenTray).BeginInvoke(null, null);
}
}
return CallNextHookEx(IntPtr.Zero, code, wParam, lParam);
}
private void OpenTray()
{
mciSendString("set CDAudio door open", null, 0, IntPtr.Zero);
}
~MyClass()
{
Uninstall();
}
}
<强> HID 强>
人机界面设备将更难与之交互。希望The Code Project可以提供帮助。
答案 1 :(得分:1)
弹出CD驱动器。不需要管理员权限。
#include <windows.h>
#include <vfw.h>
#include <stdio.h>
#pragma comment(lib, "Vfw32.lib")
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
char msg[512];
HANDLE h;
DWORD bytesreturned;
h = CreateFile("\\\\.\\cdrom0", MAXIMUM_ALLOWED, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (h == INVALID_HANDLE_VALUE)
{
sprintf(msg, "CreateFile: %u\n", GetLastError());
MessageBox(NULL, msg, "ejectcd", MB_OK);
return 1;
}
if (!DeviceIoControl(h, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, &bytesreturned, NULL))
{
sprintf(msg, "DeviceIoControl: %u\n", GetLastError());
MessageBox(NULL, msg, "ejectcd", MB_OK);
return 1;
}
return 0;
}
答案 2 :(得分:1)
我自己遇到了同样的问题。我不知道你是否熟悉autohotkeys,但用它来编写一个脚本来代替s-bar。
AutoHotKey(AHK)是Windows的开源宏创建和脚本语言,具有大量功能。您可以通过程序本身运行脚本,也可以将它们编译为可在任何计算机上运行的可执行文件。
您可以使用几行代码使弹出式CD驱动器工作:
;CD eject button
SC142::
Drive, Eject
return
SC142是键码。它可能在每台MSI笔记本电脑上都不一样,但是如果你将“#InstallKeybdHook”行放在脚本的顶部。您可以通过GUI查看AHK看到的所有键盘事件。
我能够将大多数按钮映射到我的MSI笔记本电脑上的各种功能,尽管AHK不能从其中一个捕获键盘事件。
例如:
;Star key (AHK only receives KeyUp event)
SC139 UP::
Run, Control
return
;CinemaPro Key
SC13B::
Run, "C:\Program Files\Media Player Classic\mpc-hc64.exe"
return
答案 3 :(得分:0)
答案 4 :(得分:0)
您必须使用mciSendString
API。看看这里SO link for this,如果你要以编程方式进行。
答案 5 :(得分:0)
您可以编写一个简单的程序,只需按弹出键即可轮询键盘。使用GetKeyboardState()并检查已按下的内容。或者您可以处理WM_KEYDOWN消息并在按弹出键时检查键代码。
您是否尝试过在控制面板中查找?转到控制面板&gt;监视器&gt;键设置 - 从那里您可以重新分配键盘上的键。