在编程中,经常需要与用户进行交互,获取输入或显示信息。大多数编程语言都提供了一些基本的构建块来简化这个过程。例如,在Win32中,可以使用MessageBox()函数来弹出一个消息框。另一个常用的功能是InputBox,它在VBA和Visual Basic中非常流行,用于提示用户输入。然而,在C++中,虽然可以很容易地显示消息框,但并没有直接的方法来调用类似InputBox的命令。因此,创建了一个名为SGInputBox的函数,它是一个静态库,不包含资源,可以被控制台应用程序、Win32应用程序或其他类型的C++应用程序使用。
目标是创建一个非常简单易用的InputBox函数,可以像下面这样调用:
LPWSTR result = SG_InputBox::GetString(L"Code Project Demo - by Michael Haephrati", L"What is your name");
希望看到的结果是:
或者,更好的是,可以添加一个"默认"值,这样用户就会看到这个值作为默认值,然后可以选择确认或编辑它。为了使用户体验更好,将默认文本全部选中,这样如果用户输入不同的文本,它将替换旧的文本。
为了支持默认文本(但并不强制程序员使用这个库),添加了一个可选参数:
LPWSTR GetString(LPCTSTR szCaption, LPCTSTR szPrompt, LPCTSTR szDefaultText = L"");
可以这样调用函数:
LPWSTR result = SG_InputBox::GetString(L"Code Project Demo - by Michael Haephrati", L"What is your name", L"My name is Michael");
为了测试SGInputBox函数,创建了一个默认的Windows控制台应用程序,它所做的就是链接到InputBox.lib。最好的方法是使用一个解决方案(.sln),其中包含静态库项目和测试程序项目,两者都引用$(SolutionDir)\$(Configuration)\$(Platform)\InputBox.lib。
然后,创建了一个最小的头文件,以便可以调用SGInputBox函数:
#include
class SG_InputBox {
public:
static LPWSTR GetString(LPCTSTR szCaption, LPCTSTR szPrompt, LPCTSTR szDefaultText = L"");
};
剩下的就是调用函数并使用它返回的值。
main()函数的大部分将是:
#include "SG_InputBoxLib.h"
int main() {
wprintf(L"Testing the InputBox static lib\n");
LPWSTR result = SG_InputBox::GetString(
L"Code Project Demo - by Michael Haephrati",
L"What is your name",
L"My name is Michael"
);
wprintf(L"User entered '%s'\n", result);
}
在各种文章中,总是尝试包含一些有用的代码,这些代码可以用于文章范围之外的许多目的。
为对齐文本的目的编写了setTextAlignment()函数。将其放在utils.cpp文件中,因为建议将任何辅助函数放在一组utils.cpp/utils.h源文件中,这些文件可以被其他项目使用。
void setTextAlignment(HWND hwnd, int intTextAlignment) {
LONG_PTR s;
LONG_PTR textalignment = GetWindowLongPtr(hwnd, GWL_STYLE);
if (textalignment != intTextAlignment) {
// delete the last text alignment
if (intTextAlignment == 0) {
s = GetWindowLongPtr(hwnd, GWL_STYLE);
s = s & ~(SS_LEFT);
SetWindowLongPtr(hwnd, GWL_STYLE, (LONG_PTR)s);
}
else if (intTextAlignment == 1) {
s = GetWindowLongPtr(hwnd, GWL_STYLE);
s = s & ~(SS_CENTER);
SetWindowLongPtr(hwnd, GWL_STYLE, (LONG_PTR)s);
}
else if (intTextAlignment == 2) {
s = GetWindowLongPtr(hwnd, GWL_STYLE);
s = s & ~(SS_RIGHT);
SetWindowLongPtr(hwnd, GWL_STYLE, (LONG_PTR)s);
}
textalignment = intTextAlignment;
// put the new text alignment
if (textalignment == 0) {
s = GetWindowLongPtr(hwnd, GWL_STYLE);
s = s | (SS_LEFT);
SetWindowLongPtr(hwnd, GWL_STYLE, (LONG_PTR)s);
}
else if (textalignment == 1) {
s = GetWindowLongPtr(hwnd, GWL_STYLE);
s = s | (SS_CENTER);
SetWindowLongPtr(hwnd, GWL_STYLE, (LONG_PTR)s);
}
else if (textalignment == 2) {
s = GetWindowLongPtr(hwnd, GWL_STYLE);
s = s | (SS_RIGHT);
SetWindowLongPtr(hwnd, GWL_STYLE, (LONG_PTR)s);
}
SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_DRAWFRAME);
}
}
希望确认按钮显示为默认按钮,表示如果用户按下ENTER键,它将被视为按下了该按钮。为此,使用以下代码:
// Set default button
SendMessage((HWND)m_hWndOK, BM_SETSTYLE, (WPARAM)LOWORD(BS_DEFPUSHBUTTON), MAKELPARAM(TRUE, 0));
SendMessage((HWND)m_hWndCancel, BM_SETSTYLE, (WPARAM)LOWORD(BS_PUSHBUTTON), MAKELPARAM(TRUE, 0));
首先,选择了一个漂亮的背景颜色,并定义了它,以便以后在一个地方或几个地方使用:
#define SOFT_BLUE RGB(206,214,240)
然后,定义了一个画刷:
HBRUSH SG_InputBox::hbrBkgnd = NULL;
然后,在对话框的Callback函数中:
LRESULT CALLBACK SG_InputBox::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
// Address the WM_CTLCOLORSTATIC message
case WM_CTLCOLORSTATIC: {
HDC hdcStatic = (HDC)wParam;
if (hbrBkgnd == NULL) {
hbrBkgnd = CreateSolidBrush(SOFT_BLUE);
}
SetTextColor(hdcStatic, RGB(0, 0, 0));
SetBkColor(hdcStatic, SOFT_BLUE);
return (INT_PTR)hbrBkgnd;
}
break;
}
// Set default text
SendMessage(m_hWndEdit, EM_SETSEL, 0, -1);
SendMessage(m_hWndEdit, EM_REPLACESEL, 0, (LPARAM)szDefaultText);
SendMessage(m_hWndEdit, EM_SETSEL, 0, -1);
SetFocus(m_hWndEdit);
当窗口或窗口(对话框)本身的任何元素创建失败时,调用REPORT_ERROR。这实际上是创建的一个宏:
#define REPORTERROR ReportError(__FUNCTION__)
void ReportError(const char *CallingFunction) {
DWORD error = GetLastError();
LPVOID lpMsgBuf;
DWORD bufLen = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL);
wprintf(L"%S: Error '%s'\n", CallingFunction, (wchar_t*)lpMsgBuf);
}