我创建了一个Win32应用程序并且我有一个logIn表单,但是我无法获得编辑窗口值。我是这样做的,但一无所获。我的错误在哪里?
#define passwordWindowId 2
HWND passwordWindowHandle = CreateWindow(TEXT("EDIT"), TEXT(""), WS_VISIBLE | WS_CHILD, 10, 80, 150, 20, hWnd, (HMENU)passwordWindowId, NULL, NULL);
int len = GetWindowTextLength(GetDlgItem(passwordWindowHandle, passwordEditId));
LPWSTR passwordWindowValue;
GetWindowText(passwordWindowHandle, passwordWindowValue, len + 1);
OutputDebugString(passwordWindowValue);
但如果我OutputDebugString(L"test");
,我会在输出标签中看到test
。
答案 0 :(得分:4)
你的代码中有很多错误,有些是微妙的,有些是致命的。
#define passwordWindowId 2
对话管理器使用了一些低控制ID,不应该使用用户定义的控件重载。一个常见的惯例是开始分配从100开始的数字(见Why do dialog editors start assigning control IDs with 100?)。
另一个常见的约定是为预处理程序符号使用所有大写名称。
HWND passwordWindowHandle = CreateWindow(TEXT("EDIT"), TEXT(""), ...
这是创建空编辑控件(请参阅CreateWindow的第二个参数)。这本身并不是一个错误,但你不能假设控件包含任何文本。
同样,不是错误,但使用通用文本映射通常没有帮助。将Unicode版本的API与宽字符串和字符串文字一起使用:HWND passwordWindowHandle = CreateWindowW(L"EDIT", L"", ...
。
LPWSTR passwordWindowValue;
LPWSTR
是wchar_t*
的typedef,因此上面定义了一个指针而没有初始化它。本身不是一个错误,但是当你开始使用该指针时,你会遇到未定义的行为。您需要为GetWindowText
的以下调用分配存储,方法是创建一个固定大小的本地数组,如果您提前知道最大大小,或者使用动态大小的容器(例如std::vector<wchar_t> buffer(len + 1);
)
GetWindowText(passwordWindowHandle, passwordWindowValue, len + 1);
这就是事情中断的地方:您正在请求API调用以写入未分配的内存,由未初始化的指针指向。如上所述,您需要在调用GetWindowText
之前分配内存。此外,您正在调用通用文本映射,但传递显式宽字符串类型。请改用GetWindowTextW
。
OutputDebugString(passwordWindowValue);
参数仍然是未初始化的指针。即使它不是,指向的内存也是一个空字符串,因为控制文本是空的。同样,您在传递显式宽字符串时调用通用文本映射。请改用OutputDebugStringW
。
另外,您根本不检查错误。您正在使用的所有Windows API调用都可能失败,您需要检查是否有失败。请参阅有关如何检查每个API调用的错误的文档。
答案 1 :(得分:3)
更新!!
LPWSTR passwordWindowValue;
GetWindowText(passwordWindowHandle, passwordWindowValue, len + 1);
这应该是
LPWSTR passwordWindowValue = new wchar_t[len + 1];
GetWindowText(passwordWindowHandle, passwordWindowValue, len + 1);
您正在将未经宣传的指针传递给GetWindowText
完成后删除[] passwordWindowValue。