前言
在用vs写一个简单工厂模式的demo, 随着case的增多,要新建更多的类。 vs为了防止交叉编译,为头文件生成的交叉编译宏为#pragma once 我写的是平台无关的类,到了gcc下,编译器不认得#pragma once 这时,必须自己手工将#pragma once,定义和头文件名相关的交叉编译宏 新建的类超过几个后,感觉真不好,浑身不舒服:) 花了2个小时,写了个工程,根据头文件名称生成交叉编译宏,用起来,感觉好多了^_^
效果
demo工程
src_gen_macro_for_header_file.7z 编译环境:vs2010 or vs2017 + win32sdk
工程预览
#include "stdafx.h"
#include <windows.h>
#include <stdint.h>
#include <tchar.h>
#include <stdlib.h>
#include <stdio.h>
#pragma comment(lib, "user32.lib")
#include <string>
#include <algorithm>
#include <Shellapi.h>
#pragma comment(lib, "Shell32.lib")
#include "resource.h"
#include "constDefine.h"
HINSTANCE g_hInstance = NULL;
HWND g_hMainWnd = NULL;
char g_sz_user_input[MAXBYTE] = {
'\0'};
LRESULT CALLBACK MainDlgProc(HWND, UINT, WPARAM, LPARAM);
void fnCenterWindow(HWND hWnd);
void fnSetWndText(HWND hWnd,
const TCHAR* pcTip);
void fnSetCtrlText(
int iCtrlId,
const TCHAR* pcTip);
bool gen_macro_for_header_file(
const char* psz_header_file_name,
std::
string& str_macro);
bool GetTempFolder(
std::
string &strTempFolder);
BOOL fnIsFileExist(
const char* pcFilePathName);
BOOL fnSplitFilePathName(
const char* pcPathName,
std::
string& strDriver,
std::
string& strDir,
std::
string& strFileNamePrefix,
std::
string& strFileNamePostfix);
LRESULT OnInitDialog(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT OnClose(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT OnCancel(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT OnOk(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT OnDropFiles(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
void fnTest_On_WinMain();
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
srand(NULL);
g_hInstance = hInstance;
fnTest_On_WinMain();
return DialogBox(hInstance, (LPCTSTR)IDD_MAIN_DLG, GetDesktopWindow(), (DLGPROC)MainDlgProc);
}
LRESULT CALLBACK MainDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
BOOL bRc = TRUE;
WORD wCtrlId = LOWORD(wParam);
WORD wNotifyCode = HIWORD(wParam);
HWND hSubWnd = (HWND)lParam;
switch (message) {
case WM_INITDIALOG: {
OnInitDialog(hWnd, message, wParam, lParam);
}
break;
case WM_COMMAND:
switch (wCtrlId) {
case IDCANCEL:
OnCancel(hWnd, message, wParam, lParam);
break;
case IDOK:
OnOk(hWnd, message, wParam, lParam);
break;
default:
break;
}
break;
case WM_CLOSE:
OnClose(hWnd, message, wParam, lParam);
break;
case WM_DROPFILES:
OnDropFiles(hWnd, message, wParam, lParam);
break;
default:
bRc = FALSE;
break;
}
return bRc;
}
void fnCenterWindow(HWND hWnd)
{
HWND hwndOwner;
RECT rc;
RECT rcDlg;
RECT rcOwner;
hwndOwner = GetParent(hWnd);
if (NULL == hwndOwner) {
hwndOwner = GetDesktopWindow();
}
GetWindowRect(hwndOwner, &rcOwner);
GetWindowRect(hWnd, &rcDlg);
CopyRect(&rc, &rcOwner);
OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
OffsetRect(&rc, -rc.left, -rc.top);
OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);
SetWindowPos(hWnd,
HWND_TOP,
rcOwner.left + (rc.right /
2),
rcOwner.top + (rc.bottom /
2),
0,
0,
SWP_NOSIZE);
}
void fnSetCtrlText(
int iCtrlId,
const TCHAR* pcTip)
{
HWND hWnd = NULL;
if (NULL != g_hMainWnd) {
hWnd = GetDlgItem(g_hMainWnd, iCtrlId);
fnSetWndText(hWnd, pcTip);
}
}
void fnSetWndText(HWND hWnd,
const TCHAR* pcTip)
{
if (NULL != hWnd) {
SetWindowText(hWnd, (NULL != pcTip) ? pcTip : _T(
""));
}
}
LRESULT OnInitDialog(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
g_hMainWnd = hWnd;
fnSetWndText(g_hMainWnd, G_STR_PROG_NAME);
fnCenterWindow(hWnd);
return S_OK;
}
LRESULT OnClose(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
EndDialog(hWnd, LOWORD(wParam));
return S_OK;
}
LRESULT OnCancel(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
EndDialog(hWnd, LOWORD(wParam));
return S_OK;
}
LRESULT OnDropFiles(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
POINT pt;
char sz_user_input[MAXBYTE] = {
'\0'};
char* psz_find = NULL;
UINT uFilesCnt =
0;
UINT uIndex =
0;
HDROP hDropFile = (HDROP)wParam;
DragQueryPoint(hDropFile, &pt);
uFilesCnt = DragQueryFile(hDropFile, -
1, (LPSTR) NULL,
0);
for (uIndex =
0; uIndex < uFilesCnt; uIndex++) {
memset(sz_user_input,
0,
sizeof(sz_user_input));
DragQueryFile(hDropFile, uIndex, sz_user_input,
sizeof(sz_user_input));
#if 0
memset(g_sz_user_input,
0,
sizeof(g_sz_user_input));
psz_find =
strrchr(sz_user_input,
'\\');
if (NULL != psz_find) {
strcpy(g_sz_user_input, psz_find +
1);
}
#else
strcpy(g_sz_user_input, sz_user_input);
#endif
fnSetCtrlText(IDC_EDIT, g_sz_user_input);
fnSetCtrlText(IDC_STATIC_TIP,
"请点击按钮\"生成编译宏\"");
break;
}
DragFinish(hDropFile);
return S_OK;
}
BOOL fnIsFileExist(
const char* pcFilePathName)
{
BOOL bRc = FALSE;
HANDLE hFile = INVALID_HANDLE_VALUE;
do {
if (NULL == pcFilePathName) {
break;
}
hFile = CreateFile(pcFilePathName,
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if ((NULL == hFile) || (INVALID_HANDLE_VALUE == hFile)) {
break;
}
CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE;
bRc = TRUE;
}
while (
0);
return bRc;
}
void fnTest_On_WinMain()
{
}
BOOL fnSplitFilePathName(
const char* pcPathName,
std::
string& strDriver,
std::
string& strDir,
std::
string& strFileNamePrefix,
std::
string& strFileNamePostfix)
{
char szPathName[MAX_PATH] = {
'\0'};
char szDriver[MAX_PATH] = {
'\0'};
char szDir[MAX_PATH] = {
'\0'};
char szFileNamePrefix[MAX_PATH] = {
'\0'};
char szFileNamePostfix[MAX_PATH] = {
'\0'};
if (NULL == pcPathName) {
return FALSE;
}
strcpy(szPathName, pcPathName);
_tsplitpath(szPathName,
szDriver,
szDir,
szFileNamePrefix,
szFileNamePostfix);
strDriver = szDriver;
strDir = szDir;
strFileNamePrefix = szFileNamePrefix;
strFileNamePostfix = szFileNamePostfix;
return TRUE;
}
LRESULT OnOk(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int iFileIndex =
0;
HWND hEdit = NULL;
char szBuf[MAXBYTE] = {
'\0'};
std::
string str_macro;
std::
string strTempFilePathName;
FILE* pfile = NULL;
SHELLEXECUTEINFOA ShExecInfo = {
0};
fnSetCtrlText(IDC_STATIC_TIP,
"...");
hEdit = ::GetDlgItem(g_hMainWnd, IDC_EDIT);
::GetWindowText(hEdit, g_sz_user_input,
sizeof(g_sz_user_input));
if (gen_macro_for_header_file(g_sz_user_input, str_macro)) {
GetTempFolder(strTempFilePathName);
sprintf(szBuf,
"gen_macro_for_header_%d.txt", rand());
strTempFilePathName += szBuf;
pfile = fopen(strTempFilePathName.c_str(),
"w");
if (NULL != pfile) {
fwrite(str_macro.data(), str_macro.length(),
sizeof(
char), pfile);
fclose(pfile);
pfile = NULL;
ShExecInfo.cbSize =
sizeof(SHELLEXECUTEINFOA);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = NULL;
ShExecInfo.lpFile =
"notepad.exe";
ShExecInfo.lpParameters = strTempFilePathName.c_str();
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOWNORMAL;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);
WaitForSingleObject(ShExecInfo.hProcess,INFINITE);
DeleteFileA(strTempFilePathName.c_str());
}
}
else {
fnSetCtrlText(IDC_STATIC_TIP,
"请输入头文件名称 :)");
}
return S_OK;
}
bool GetTempFolder(
std::
string &strTempFolder)
{
char sz_buf[MAX_PATH *
2] = {
'\0'};
GetTempPathA(
sizeof(sz_buf), sz_buf);
strTempFolder = sz_buf;
return true;
}
bool gen_macro_for_header_file(
const char* psz_header_file_name,
std::
string& str_macro)
{
bool b_rc =
false;
int8_t sz_buf[MAXBYTE *
4] = {
'\0'};
std::
string str_tmp =
"";
std::
string str_macro_name =
"";
do {
str_macro =
"";
if ((NULL == psz_header_file_name) || (
strlen(psz_header_file_name) <=
0)) {
break;
}
sprintf((
char*)sz_buf,
"// @file : %s\n", psz_header_file_name);
str_macro += (
char*)sz_buf;
sprintf((
char*)sz_buf,
"// @brief : ...\n");
str_macro += (
char*)sz_buf;
str_tmp = psz_header_file_name;
std::transform(str_tmp.begin(), str_tmp.end(), str_tmp.begin(), ::
toupper);
std::replace(str_tmp.begin(), str_tmp.end(),
':',
'_');
std::replace(str_tmp.begin(), str_tmp.end(),
'.',
'_');
std::replace(str_tmp.begin(), str_tmp.end(),
'\\',
'_');
str_macro_name +=
"__";
str_macro_name += str_tmp.c_str();
str_macro_name +=
"__";
sprintf((
char*)sz_buf,
"#ifndef %s\n", str_macro_name.c_str());
str_macro += (
char*)sz_buf;
sprintf((
char*)sz_buf,
"#define %s\n", str_macro_name.c_str());
str_macro += (
char*)sz_buf;
str_macro +=
"\r\n\r\n";
sprintf((
char*)sz_buf,
"#endif // #define %s\n", str_macro_name.c_str());
str_macro += (
char*)sz_buf;
b_rc =
true;
}
while (
0);
return b_rc;
}