您的位置:首页 > 其它

tools: generate cross-compiled macros for header file

2018-01-24 00:24 260 查看

前言

在用vs写一个简单工厂模式的demo, 随着case的增多,要新建更多的类。

vs为了防止交叉编译,为头文件生成的交叉编译宏为#pragma once

我写的是平台无关的类,到了gcc下,编译器不认得#pragma once

这时,必须自己手工将#pragma once,定义和头文件名相关的交叉编译宏

新建的类超过几个后,感觉真不好,浑身不舒服:)

花了2个小时,写了个工程,根据头文件名称生成交叉编译宏,用起来,感觉好多了^_^

效果





demo工程

src_gen_macro_for_header_file.7z

编译环境:vs2010 or vs2017 + win32sdk

工程预览

// hw.cpp : Defines the entry point for the application.
//

#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
// 只保留头文件名 e.g. x.h
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
// 既然是拖入文件, 由用户再二次编辑头文件名全路径后,再生成宏
// e.g. drop file is "c:\x_dir1\x_dir2\x.h"
// edit to "x_dir2\x.h" then gen macro as "__X_DIR2_X_H__"
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,  // file name
GENERIC_READ,                   // open for reading
0,                              // do not share
NULL,                           // default security
OPEN_EXISTING,                  // existing file only
FILE_ATTRIBUTE_NORMAL,   // normal file
NULL);                          // no template

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);
// _splitpath 的反函数_makepath
_tsplitpath(szPathName,
szDriver,
szDir,
szFileNamePrefix,
szFileNamePostfix);
strDriver = szDriver;
strDir = szDir;
strFileNamePrefix = szFileNamePrefix;
strFileNamePostfix = szFileNamePostfix;
/** note
* csPathName = c:\subDir1\subDir2\subDir3\test1.dat  * csDriver = c:
* csDir = \subDir1\subDir2\subDir3\
* csFileNamePrefix = test1
* csFileNamePostfix = .dat
*/
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐