使用 Win32 Visual C++ 在没有硬编码驱动器号的情况下弹出 CDRom 驱动器
Ejecting CDRom Drive without hardcoding drive letter using Win32 Visual C++
我试图通过单击按钮弹出我的 CDRom 驱动器。这在 CDRom 驱动器盘符被硬编码时有效,但我想在不对 CDRom 驱动器进行硬编码的情况下执行此操作。如果我在我的计算机上找到 CDRom 驱动器并将其保存到 'TCHAR drive_letter',我如何将它拉入下面的代码?出于某种原因,它不允许我做 'EjectCdTray(drive_letter);'。代码如下:
#include <tchar.h>
#include <windows.h>
#include <mmsystem.h> // for MCI functions
// Link to winmm.lib (usually included in project settings)
#pragma comment(lib, "winmm")
#define BUTTON 3456
LPWSTR pBuf = buf;
DWORD chrCopied = GetLogicalDriveStrings(BUF_SIZE - 1, buf);
TCHAR drive_letter[200];
void ControlCdTray(TCHAR drive, DWORD command)
{
// Not used here, only for debug
MCIERROR mciError = 0;
// Flags for MCI command
DWORD mciFlags = MCI_WAIT | MCI_OPEN_SHAREABLE |
MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID | MCI_OPEN_ELEMENT;
// Open drive device and get device ID
TCHAR elementName[] = { drive };
MCI_OPEN_PARMS mciOpenParms = { 0 };
mciOpenParms.lpstrDeviceType = (LPCTSTR)MCI_DEVTYPE_CD_AUDIO;
mciOpenParms.lpstrElementName = elementName;
mciError = mciSendCommand(0,
MCI_OPEN, mciFlags, (DWORD_PTR)&mciOpenParms);
// Eject or close tray using device ID
MCI_SET_PARMS mciSetParms = { 0 };
mciFlags = MCI_WAIT | command; // command is sent by caller
mciError = mciSendCommand(mciOpenParms.wDeviceID,
MCI_SET, mciFlags, (DWORD_PTR)&mciSetParms);
// Close device ID
mciFlags = MCI_WAIT;
MCI_GENERIC_PARMS mciGenericParms = { 0 };
mciError = mciSendCommand(mciOpenParms.wDeviceID,
MCI_CLOSE, mciFlags, (DWORD_PTR)&mciGenericParms);
}
// Eject drive tray
void EjectCdTray(TCHAR drive)
{
ControlCdTray(drive, MCI_SET_DOOR_OPEN);
}
// Retract drive tray
void CloseCdTray(TCHAR drive)
{
ControlCdTray(drive, MCI_SET_DOOR_CLOSED);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
while (chrCopied)
{
if (DRIVE_CDROM == GetDriveType(pBuf))
{
wsprintf(drive_letter, L"%s", pBuf);
size_t indexOfNull2 = _tcslen(drive_letter);
drive_letter[indexOfNull2 - 2] = '[=10=]';
}
size_t len = _tcslen(buf);
chrCopied -= len + 1;
pBuf += len + 1;
}
HWND hwndButton = CreateWindow(
L"BUTTON", // Predefined class; Unicode assumed
L"EJECT", // Button text
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // Styles
180, // x position
200, // y position
100, // Button width
100, // Button height
hWnd, // Parent window
(HMENU)BUTTON, // No menu.
(HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
NULL); // Pointer not needed.
}
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case BUTTON:
EjectCdTray(drive_letter); // TCHAR drive_letter = L"D";
MessageBox(NULL, L"Please insert a CD ROM in the CD tray.", L"CD ROM Drive", 0);
break;
}
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
首先声明drive_letter
变量,
TCHAR drive_letter;
根据自己的需要,创建一个需要获取盘符的函数,然后将值传给它。
drive_letter = Get_driverletter();
这一行,// TCHAR drive_letter = L"D";
应该是'D'.
"D" => 字符串
'D' => 字符
更新:
你是这个意思吗?
TCHAR drive_letter[100] = L"D";
EjectCdTray(drive_letter[0]); // TCHAR drive_letter = L"D";
MCI_OPEN_PARMS::lpstrElementName
需要一个以 null 结尾的字符串,但您没有给它。您正在将单个字符转换为字符数组,而没有向其添加空终止符。
尝试像这样设置 elementName
:
TCHAR elementName[] = TEXT("?:\");
elementName[0] = drive;
或:
TCHAR elementName[] = { drive, TEXT(':'), TEXT('\'), TEXT('[=11=]') );
然后,您需要像这样调用函数:
EjectCdTray(drive_letter[0]);
否则,更改您的函数以将整个驱动器路径作为字符串接受,根本不要将其缩减为单个字符:
...
TCHAR drive_path[MAX_PATH] = {};
void ControlCdTray(LPCTSTR drive, DWORD command)
{
...
mciOpenParms.lpstrElementName = drive;
...
}
void EjectCdTray(LPCTSTR drive)
{
ControlCdTray(drive, MCI_SET_DOOR_OPEN);
}
void CloseCdTray(LPCTSTR drive)
{
ControlCdTray(drive, MCI_SET_DOOR_CLOSED);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
...
wsprintf(drive_path, L"%s", pBuf);
EjectCdTray(drive_path); // TCHAR drive_path[] = L"D:\";
...
return 0;
}
我试图通过单击按钮弹出我的 CDRom 驱动器。这在 CDRom 驱动器盘符被硬编码时有效,但我想在不对 CDRom 驱动器进行硬编码的情况下执行此操作。如果我在我的计算机上找到 CDRom 驱动器并将其保存到 'TCHAR drive_letter',我如何将它拉入下面的代码?出于某种原因,它不允许我做 'EjectCdTray(drive_letter);'。代码如下:
#include <tchar.h>
#include <windows.h>
#include <mmsystem.h> // for MCI functions
// Link to winmm.lib (usually included in project settings)
#pragma comment(lib, "winmm")
#define BUTTON 3456
LPWSTR pBuf = buf;
DWORD chrCopied = GetLogicalDriveStrings(BUF_SIZE - 1, buf);
TCHAR drive_letter[200];
void ControlCdTray(TCHAR drive, DWORD command)
{
// Not used here, only for debug
MCIERROR mciError = 0;
// Flags for MCI command
DWORD mciFlags = MCI_WAIT | MCI_OPEN_SHAREABLE |
MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID | MCI_OPEN_ELEMENT;
// Open drive device and get device ID
TCHAR elementName[] = { drive };
MCI_OPEN_PARMS mciOpenParms = { 0 };
mciOpenParms.lpstrDeviceType = (LPCTSTR)MCI_DEVTYPE_CD_AUDIO;
mciOpenParms.lpstrElementName = elementName;
mciError = mciSendCommand(0,
MCI_OPEN, mciFlags, (DWORD_PTR)&mciOpenParms);
// Eject or close tray using device ID
MCI_SET_PARMS mciSetParms = { 0 };
mciFlags = MCI_WAIT | command; // command is sent by caller
mciError = mciSendCommand(mciOpenParms.wDeviceID,
MCI_SET, mciFlags, (DWORD_PTR)&mciSetParms);
// Close device ID
mciFlags = MCI_WAIT;
MCI_GENERIC_PARMS mciGenericParms = { 0 };
mciError = mciSendCommand(mciOpenParms.wDeviceID,
MCI_CLOSE, mciFlags, (DWORD_PTR)&mciGenericParms);
}
// Eject drive tray
void EjectCdTray(TCHAR drive)
{
ControlCdTray(drive, MCI_SET_DOOR_OPEN);
}
// Retract drive tray
void CloseCdTray(TCHAR drive)
{
ControlCdTray(drive, MCI_SET_DOOR_CLOSED);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
while (chrCopied)
{
if (DRIVE_CDROM == GetDriveType(pBuf))
{
wsprintf(drive_letter, L"%s", pBuf);
size_t indexOfNull2 = _tcslen(drive_letter);
drive_letter[indexOfNull2 - 2] = '[=10=]';
}
size_t len = _tcslen(buf);
chrCopied -= len + 1;
pBuf += len + 1;
}
HWND hwndButton = CreateWindow(
L"BUTTON", // Predefined class; Unicode assumed
L"EJECT", // Button text
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // Styles
180, // x position
200, // y position
100, // Button width
100, // Button height
hWnd, // Parent window
(HMENU)BUTTON, // No menu.
(HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
NULL); // Pointer not needed.
}
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case BUTTON:
EjectCdTray(drive_letter); // TCHAR drive_letter = L"D";
MessageBox(NULL, L"Please insert a CD ROM in the CD tray.", L"CD ROM Drive", 0);
break;
}
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
首先声明drive_letter
变量,
TCHAR drive_letter;
根据自己的需要,创建一个需要获取盘符的函数,然后将值传给它。
drive_letter = Get_driverletter();
这一行,// TCHAR drive_letter = L"D";
应该是'D'.
"D" => 字符串
'D' => 字符
更新:
你是这个意思吗?
TCHAR drive_letter[100] = L"D";
EjectCdTray(drive_letter[0]); // TCHAR drive_letter = L"D";
MCI_OPEN_PARMS::lpstrElementName
需要一个以 null 结尾的字符串,但您没有给它。您正在将单个字符转换为字符数组,而没有向其添加空终止符。
尝试像这样设置 elementName
:
TCHAR elementName[] = TEXT("?:\");
elementName[0] = drive;
或:
TCHAR elementName[] = { drive, TEXT(':'), TEXT('\'), TEXT('[=11=]') );
然后,您需要像这样调用函数:
EjectCdTray(drive_letter[0]);
否则,更改您的函数以将整个驱动器路径作为字符串接受,根本不要将其缩减为单个字符:
...
TCHAR drive_path[MAX_PATH] = {};
void ControlCdTray(LPCTSTR drive, DWORD command)
{
...
mciOpenParms.lpstrElementName = drive;
...
}
void EjectCdTray(LPCTSTR drive)
{
ControlCdTray(drive, MCI_SET_DOOR_OPEN);
}
void CloseCdTray(LPCTSTR drive)
{
ControlCdTray(drive, MCI_SET_DOOR_CLOSED);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
...
wsprintf(drive_path, L"%s", pBuf);
EjectCdTray(drive_path); // TCHAR drive_path[] = L"D:\";
...
return 0;
}