我是用C ++开发Win32 API的新手,我已经制作了第一个这样的程序:
以下是我的代码,但如果你想构建它,那么这就是我的project archive。
// The feedback interface with GUI.
#include "stdafx.h"
#include "Win32Project1.h"
#include <string>
#include <fstream>
#include <Windows.h>
#define MAX_LOADSTRING 65536
#include <strsafe.h>
HFONT defaultFont;
HWND hwnd2;
HWND Button;
HWND Help;
void ErrorExit(LPTSTR lpszFunction) //Function used for debugging
{
// Retrieve the system error message for the last-error code
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf,
0, NULL);
// Display the error message and exit the process
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR), 0);
}
LPWSTR Convert(const std::string& s)
{
LPWSTR ws = new wchar_t[s.size() + 1]; // +1 for zero at the end
copy(s.begin(), s.end(), ws);
ws[s.size()] = 0; // zero at the end
return ws;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
TCHAR Feedback[MAX_LOADSTRING];
std::string Msg;
std::string MsgTitle;
std::ofstream FeedbackFile;
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
// Get UI font
NONCLIENTMETRICS ncm;
ncm.cbSize = sizeof(ncm);
// If we're compiling with the Vista SDK or later, the NONCLIENTMETRICS struct
// will be the wrong size for previous versions, so we need to adjust it.
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0);
defaultFont = CreateFontIndirect(&(ncm.lfMessageFont));
// Register the window class.
std::string CLASS_NAME = "The first program!";
WNDCLASS wc = {};
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = L"First program!";
RegisterClass(&wc);
// Create the window.
HWND hwnd = CreateWindowEx(
WS_EX_CONTEXTHELP, // Optional window styles.
L"First program!", // Window class
L"The first program!", // Window text
WS_OVERLAPPEDWINDOW, // Window style
// Size and position
0, 0, 640, 360,
NULL, // Parent window
NULL, // Menu
hInstance, // Instance handle
NULL // Additional application data
);
if (hwnd == NULL)
{
return 0;
}
ShowWindow(hwnd, nCmdShow);
// Create the window.
hwnd2 = CreateWindowEx(
WS_EX_CLIENTEDGE, // Optional window styles.
L"edit", // Window class
L"Insert feedback here :)", // Window text
WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER | ES_LEFT | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL, // Window style
// Size and position
10, 50, 300, 200,
hwnd, // Parent window
(HMENU)(123), // Menu
(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), // Instance handle
NULL // Additional application data
);
Button = CreateWindowW(
L"BUTTON",
L"Submit feedback!",
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
160, 255, 150, 20,
hwnd,
(HMENU) BT_PRESS,
(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE),
NULL
);
Help = CreateWindowW(
L"BUTTON",
L"What is this?",
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
10, 280, 80, 20,
hwnd,
(HMENU)HELP_PRESS,
(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE),
NULL
);
SendMessage(hwnd2, WM_SETFONT, WPARAM(defaultFont), TRUE);
SendMessage(Button, WM_SETFONT, WPARAM(defaultFont), TRUE);
SendMessage(Help, WM_SETFONT, WPARAM(defaultFont), TRUE);
if (hwnd2 == NULL)
{
return 0;
}
ShowWindow(hwnd2, nCmdShow);
// Run the message loop.
MSG msg = {};
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_HELP:
MessageBox(Help, L"This is my first program made by Visual Studio 2017.\nYou can type your feedback in the box and then press Submit feedback!\nYour feedback will be saved and we will read it.\n\nThanks so much for using this program. :)", L"About this program", MB_OK);
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
SelectObject(hdc, defaultFont);
FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
TextOut(hdc, 10, 5, TEXT("Hi! This is my first program made by Visual Studio 2017."), 57);
TextOut(hdc, 10, 20, TEXT("Do you have something to tell me?"), 34);
TextOut(hdc, 10, 35, TEXT("Just write below and I will listen. :)"), 39);
EndPaint(hwnd, &ps);
}
case WM_COMMAND:
{
switch (wParam)
{
case BT_PRESS:
{
GetWindowText(hwnd2, Feedback, MAX_LOADSTRING);
FeedbackFile.open("Feedback.txt", std::ios::out | std::ios::app);
FeedbackFile << Feedback;
FeedbackFile << "\n------------------------\n";
FeedbackFile.close();
LPWSTR Msg = L"Thanks for your feedback! I appreciated!";
LPWSTR MsgTitle = L"Feedback accepted!";
MessageBox(hwnd, Msg, MsgTitle, MB_OK);
SendMessage(hwnd, WM_DESTROY, NULL, NULL);
} break;
case HELP_PRESS:
SendMessage(hwnd, WM_HELP, 0, 0);
break;
}
}
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
我打算让程序显示一个消息框,告诉用户该程序,然后单击“确定”,框关闭,程序仍在那里。但是当单击“确定”按钮时,消息框消失,程序也关闭。 在用户单击“确定”后,是否仍然保持程序运行?非常感谢你。
答案 0 :(得分:0)
您不应使用 SendMessage (hwnd,WM_DESTROY,NULL,NULL);这基本上告诉程序退出。
MessageBox ()是一个阻止调用。无需在消息队列中发布消息。
这将是您的新WM_COMMAND (更新1)
case WM_COMMAND:
{
switch (wParam)
{
case BT_PRESS:
{
GetWindowText(hwnd2, Feedback, MAX_LOADSTRING);
FeedbackFile.open("Feedback.txt", std::ios::out | std::ios::app);
FeedbackFile << Feedback;
FeedbackFile << "\n------------------------\n";
FeedbackFile.close();
LPWSTR Msg = L"Thanks for your feedback! I appreciated!";
LPWSTR MsgTitle = L"Feedback accepted!";
MessageBox(hwnd, Msg, MsgTitle, MB_OK);
SendMessage(hwnd2, WM_DESTROY, NULL, NULL);
} break;
case HELP_PRESS:
SendMessage(hwnd, WM_HELP, 0, 0);
break;
}
}
答案 1 :(得分:0)
我看到的第一个问题是break
结构的某些部分缺少switch
语句。
如果return
是零件的最后一个陈述,则这不是问题:
case WM_DESTROY:
PostQuitMessage(0);
return 0;
break; // This line has no effect after a return
但是,如果既没有break
也没有return
语句,您就会遇到问题:
case WM_HELP:
MessageBox(Help, ... , MB_OK);
// break; <- This line is missing in your program!
case WM_DESTROY:
PostQuitMessage(0);
在这种情况下,WM_DESTROY
部分将在WM_HELP
部分之后输入。显示MessageBox
后,将执行PostQuitMessage
功能,这将停止您的程序。
答案 2 :(得分:-1)
好的,经过2天的编辑和调试,我终于得到了自己的答案。我想也许是消息循环
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
是问题所在。所以我添加了BOOL帮助并编辑了这样的代码:
//Message loop in the wWinMain function
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (helped) {
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
} //Repeat the loop again if user clicked "What is this?"
//The HELP_PRESS handle in WM_COMMAND
case HELP_PRESS:
SendMessage(hwnd, WM_HELP, 0, 0);
helped = true;
break;
无论如何,感谢 Suraj S 和 i486 这么多试图帮助我。我希望这可以帮助其他编码人员遇到同样的问题。再一次,非常感谢。