Skip to content

Instantly share code, notes, and snippets.

@yak1ex
Last active January 16, 2018 11:19
Show Gist options
  • Save yak1ex/cde679e96bb334781a2c9e6ff66a1228 to your computer and use it in GitHub Desktop.
Save yak1ex/cde679e96bb334781a2c9e6ff66a1228 to your computer and use it in GitHub Desktop.
About dialog from version resource
#include <windows.h>
#include <Strsafe.h>
#include <vector>
#include <boost/align/aligned_allocator.hpp>
#include <iostream>
#include <iomanip>
typedef boost::alignment::aligned_allocator<void, 4> aligned_allocator;
class buffer
{
public:
buffer() : buf(aligned_allocator()) { buf.reserve(100); }
void align(std::size_t size)
{
std::size_t pad = size - buf.size() % size;
if(pad != size) buf.insert(buf.end(), pad , 0);
}
template<typename T>
void add(const T& t)
{
auto st = static_cast<const char*>(static_cast<const void*>(&t));
buf.insert(buf.end(), st, st + sizeof(T));
}
void add(LPCWSTR lp)
{
std::size_t len = lstrlenW(lp);
auto st = static_cast<const char*>(static_cast<const void*>(lp));
buf.insert(buf.end(), st, st+(len+1)*sizeof(WCHAR));
}
void add(const std::wstring& w)
{
auto st = static_cast<const char*>(static_cast<const void*>(w.data()));
buf.insert(buf.end(), st, st+(w.size()+1)*sizeof(WCHAR));
}
const char* data() const { return buf.data(); }
std::size_t size() const { return buf.size(); }
private:
std::vector<char, aligned_allocator> buf;
};
INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg) {
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam)) {
case IDOK:
EndDialog(hwndDlg, 0);
break;
}
break;
case WM_CLOSE:
EndDialog(hwndDlg, 0);
return TRUE;
}
return FALSE;
}
// TODO: specify position
// TODO: size adjustment
// TODO: icon control
int main(void)
{
char buf[2048];
GetModuleFileName(0, buf, sizeof(buf));
DWORD dwSize = GetFileVersionInfoSize(buf, 0);
std::vector<char> v(dwSize);
GetFileVersionInfo(buf, 0, dwSize, v.data());
struct LANGANDCODEPAGE {
WORD wLanguage;
WORD wCodePage;
} *lpTranslate;
UINT uiLen;
VerQueryValue(v.data(), "\\VarFileInfo\\Translation", (LPVOID*)&lpTranslate, &uiLen);
UINT uiIdx = 0, uiPrior = 0;
for(UINT i = 1; i < uiLen / sizeof(*lpTranslate); ++i) {
UINT uiTemp = 0;
if(lpTranslate[i].wLanguage == 0x0411 && lpTranslate[i].wCodePage == 0x03A4) { // JP, SJIS
uiTemp = 4;
} else if(lpTranslate[i].wLanguage == 0x0411) { // JP
uiTemp = 3;
} else if(lpTranslate[i].wLanguage == 0x0409 && lpTranslate[i].wCodePage == 0x04E4) { // ENG, ANSI
uiTemp = 2;
} else if(lpTranslate[i].wLanguage == 0x0409) { // ENG
uiTemp = 1;
}
if(uiTemp > uiPrior) {
uiTemp = uiPrior;
uiIdx = i;
}
}
WCHAR wbuf[128];
LPWSTR lp;
UINT uiSize;
StringCbPrintfW(wbuf, sizeof(wbuf), L"\\StringFileInfo\\%04x%04x\\ProductName", lpTranslate[uiIdx].wLanguage, lpTranslate[uiIdx].wCodePage);
VerQueryValueW(v.data(), wbuf, (LPVOID*)&lp, &uiSize);
std::wstring wsProductName(lp);
StringCbPrintfW(wbuf, sizeof(wbuf), L"\\StringFileInfo\\%04x%04x\\ProductVersion", lpTranslate[uiIdx].wLanguage, lpTranslate[uiIdx].wCodePage);
VerQueryValueW(v.data(), wbuf, (LPVOID*)&lp, &uiSize);
std::wstring wsProductVersion(lp);
StringCbPrintfW(wbuf, sizeof(wbuf), L"\\StringFileInfo\\%04x%04x\\FileDescription", lpTranslate[uiIdx].wLanguage, lpTranslate[uiIdx].wCodePage);
VerQueryValueW(v.data(), wbuf, (LPVOID*)&lp, &uiSize);
std::wstring wsFileDescription(lp);
StringCbPrintfW(wbuf, sizeof(wbuf), L"\\StringFileInfo\\%04x%04x\\LegalCopyright", lpTranslate[uiIdx].wLanguage, lpTranslate[uiIdx].wCodePage);
VerQueryValueW(v.data(), wbuf, (LPVOID*)&lp, &uiSize);
std::wstring wsLegalCopyright(lp);
buffer buffer;
// DLGTEMPLATEEX
buffer.add<WORD>(1); // dlgVer
buffer.add<WORD>(0xFFFF); // signature
buffer.add<DWORD>(0); // helpID
buffer.add<DWORD>(0); // exStyle
buffer.add<DWORD>(DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_POPUP | WS_SYSMENU);
// style
buffer.add<WORD>(4); // cDlgItems
buffer.add<short>(0); // x
buffer.add<short>(0); // y
buffer.add<short>(140); // cx
buffer.add<short>(80); // cy
buffer.add<WORD>(0); // menu
buffer.add<WORD>(0); // windowClass
buffer.add(L"About"); // title
buffer.add<WORD>(8); // pointsize
buffer.add<WORD>(400); // weight
buffer.add<BYTE>(0); // italic
buffer.add<BYTE>(1); // charset
buffer.add(L"MS Shell Dlg");
// typeface
// DLGITEMTEMPLATEEX
buffer.align(4);
buffer.add<DWORD>(0); // helpID
buffer.add<DWORD>(0); // exStyle
buffer.add<DWORD>(SS_LEFT | WS_VISIBLE);
// style
buffer.add<short>(10); // x
buffer.add<short>(10); // y
buffer.add<short>(120); // cx
buffer.add<short>(7); // cy
buffer.add<DWORD>(-1); // id
buffer.add<WORD>(0xFFFF); // windowClass
buffer.add<WORD>(0x0082);
buffer.add(wsProductName + L" " + wsProductVersion);
// title
buffer.add<WORD>(0); // extraCount
buffer.align(4);
buffer.add<DWORD>(0); // helpID
buffer.add<DWORD>(0); // exStyle
buffer.add<DWORD>(SS_LEFT | WS_VISIBLE);
// style
buffer.add<short>(10); // x
buffer.add<short>(30); // y
buffer.add<short>(120); // cx
buffer.add<short>(7); // cy
buffer.add<DWORD>(-1); // id
buffer.add<WORD>(0xFFFF); // windowClass
buffer.add<WORD>(0x0082);
buffer.add(wsFileDescription);
// title
buffer.add<WORD>(0); // extraCount
buffer.align(4);
buffer.add<DWORD>(0); // helpID
buffer.add<DWORD>(0); // exStyle
buffer.add<DWORD>(SS_LEFT | WS_VISIBLE);
// style
buffer.add<short>(10); // x
buffer.add<short>(40); // y
buffer.add<short>(120); // cx
buffer.add<short>(7); // cy
buffer.add<DWORD>(-1); // id
buffer.add<WORD>(0xFFFF); // windowClass
buffer.add<WORD>(0x0082);
buffer.add(wsLegalCopyright);
// title
buffer.add<WORD>(0); // extraCount
buffer.align(4);
buffer.add<DWORD>(0); // helpID
buffer.add<DWORD>(0); // exStyle
buffer.add<DWORD>(BS_DEFPUSHBUTTON | WS_TABSTOP | WS_VISIBLE);
// style
buffer.add<short>(45); // x
buffer.add<short>(60); // y
buffer.add<short>(50); // cx
buffer.add<short>(14); // cy
buffer.add<DWORD>(IDOK); // id
buffer.add<WORD>(0xFFFF); // windowClass
buffer.add<WORD>(0x0080);
buffer.add(L"OK"); // title
buffer.add<WORD>(0); // extraCount
DialogBoxIndirect(GetModuleHandle(0), reinterpret_cast<LPCDLGTEMPLATE>(buffer.data()), 0, DialogProc);
return 0;
}
#include <windows.h>
//
// Version Information resources
//
1 VERSIONINFO
FILEVERSION 0,1,2015,105
PRODUCTVERSION 0,1,2015,105
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE VFT2_UNKNOWN
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS 0x00000000
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "041103A4"
BEGIN
VALUE "CompanyName", "Yak!"
VALUE "FileDescription", "Some file description"
VALUE "FileVersion", "Ver 0.01 (2015/01/05)"
VALUE "InternalName", "filename.ext"
VALUE "LegalCopyright", "Written by Yak!"
VALUE "OriginalFilename", "filename.ext"
VALUE "ProductName", "filename.ext"
VALUE "ProductVersion", "Ver 0.01 (2015/01/05)"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0411, 0x03A4
END
END
dlg.exe: dlg.obj dlg.res
cl /EHsc /I c:\usr\local\boost dlg.obj dlg.res user32.lib version.lib
dlg.obj: dlg.cpp
cl /EHsc /c /I c:\usr\local\boost dlg.cpp
dlg.res: dlg.rc
rc dlg.rc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment