NSIS/Contrib/LangDLL/LangDLL.c
anders_k 7cc150c464 MakeNSIS can now generate Unicode or Ansi installers based on a script attribute. SCons generates both Ansi and Unicode stubs and plugins.
The official plugins are now stored in architecture specific subdirectories under NSIS\Plugins. !AddPluginDir also gained a new (optional) architecture flag because MakeNSIS now stores separate plugin information for each target architecture. Storing plugins in the root of the Plugins directory is no longer supported.

MinGW does not implement the unicode CRT startup functions so the entry point functions and linker parameters had to be changed. The unicode tools use the ansi entry point and a small helper function that calls into the real code: _tmain has full argc+argv emulation while wWinMain does not pass the command line parameters. The stubs do not use any CRT functions and have no CRT or unicode helper code, they call our entry point directly.



git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6269 212acab6-be3b-0410-9dea-997c60f758d6
2012-10-13 01:47:50 +00:00

244 lines
6.8 KiB
C

#include <windows.h>
#include "resource.h"
#include <nsis/nsis_tchar.h>
// JF> updated usage
// call like this:
// LangDLL:LangDialog "Window Title" "Window subtext" <number of languages>[F] language_text language_id ... [font_size font_face]
// ex:
// LangDLL:LangDialog "Language Selection" "Choose a language" 2 French 1036 English 1033
// or (the F after the 2 means we're supplying font information)
// LangDLL:LangDialog "Language Selection" "Choose a language" 2F French 1036 English 1033 12 Garamond
//
// Unicode support added by Jim Park -- 07/27/2007
#include <nsis/pluginapi.h> // nsis plugin
HINSTANCE g_hInstance;
HWND g_hwndParent;
TCHAR temp[1024];
TCHAR g_wndtitle[1024], g_wndtext[1024];
int dofont;
int docp;
int langs_num;
int visible_langs_num;
struct lang {
TCHAR *name;
TCHAR *id;
UINT cp;
} *langs;
BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int i, size;
TCHAR *selected_language = NULL;
static HFONT font;
switch (uMsg) {
case WM_INITDIALOG:
// add languages
for (i = visible_langs_num - 1; i >= 0; i--) {
int cbi;
cbi = SendDlgItemMessage(hwndDlg, IDC_LANGUAGE, CB_ADDSTRING, 0, (LPARAM) langs[i].name);
SendDlgItemMessage(hwndDlg, IDC_LANGUAGE, CB_SETITEMDATA, cbi, (LPARAM) langs[i].id);
// remember selected language
if (!lstrcmp(langs[i].id, getuservariable(INST_LANG))) {
selected_language = langs[i].name;
}
}
// select the current language
if (selected_language)
SendDlgItemMessage(hwndDlg, IDC_LANGUAGE, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) selected_language);
else
SendDlgItemMessage(hwndDlg, IDC_LANGUAGE, CB_SETCURSEL, 0, 0);
// set texts
SetDlgItemText(hwndDlg, IDC_TEXT, g_wndtext);
SetWindowText(hwndDlg, g_wndtitle);
SendDlgItemMessage(hwndDlg, IDC_APPICON, STM_SETICON, (LPARAM)LoadIcon(GetModuleHandle(0),MAKEINTRESOURCE(103)), 0);
// set font
if (dofont && !popstring(temp)) {
size = myatou(temp);
if (!popstring(temp)) {
LOGFONT f = {0,};
if (lstrcmp(temp, _T("MS Shell Dlg"))) {
f.lfHeight = -MulDiv(size, GetDeviceCaps(GetDC(hwndDlg), LOGPIXELSY), 72);
lstrcpy(f.lfFaceName, temp);
font = CreateFontIndirect(&f);
SendMessage(hwndDlg, WM_SETFONT, (WPARAM)font, 1);
SendDlgItemMessage(hwndDlg, IDOK, WM_SETFONT, (WPARAM)font, 1);
SendDlgItemMessage(hwndDlg, IDCANCEL, WM_SETFONT, (WPARAM)font, 1);
SendDlgItemMessage(hwndDlg, IDC_LANGUAGE, WM_SETFONT, (WPARAM)font, 1);
SendDlgItemMessage(hwndDlg, IDC_TEXT, WM_SETFONT, (WPARAM)font, 1);
}
}
}
// show window
ShowWindow(hwndDlg, SW_SHOW);
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
// push result on the stack
i = SendDlgItemMessage(hwndDlg, IDC_LANGUAGE, CB_GETCURSEL, 0, 0);
i = SendDlgItemMessage(hwndDlg, IDC_LANGUAGE, CB_GETITEMDATA, i, 0);
if (i != CB_ERR && i) {
pushstring((TCHAR *) i);
} else {
// ?!
pushstring(_T("cancel"));
}
// end dialog
EndDialog(hwndDlg, 0);
break;
case IDCANCEL:
// push "cancel" on the stack
pushstring(_T("cancel"));
// end dialog
EndDialog(hwndDlg, 0);
break;
}
break;
case WM_DESTROY:
// clean up
if (font) DeleteObject(font);
break;
default:
return FALSE; // message not processed
}
return TRUE; // message processed
}
void __declspec(dllexport) LangDialog(HWND hwndParent, int string_size,
TCHAR *variables, stack_t **stacktop)
{
g_hwndParent=hwndParent;
EXDLL_INIT();
{
int i;
int doauto = 0;
BOOL pop_empty_string = FALSE;
// get texts
if (popstring(g_wndtitle)) return;
if (popstring(g_wndtext)) return;
// get flags
if (popstring(temp)) return;
// parse flags
{
TCHAR *p=temp;
while (*p)
{
if (*p == _T('A')) doauto=1; // parse auto count flag
if (*p == _T('F')) dofont=1; // parse font flag
if (*p == _T('C')) docp=1; // parse codepage flag
p++;
}
}
if (doauto) {
// automatic language count
stack_t *th;
langs_num=0;
th=(*g_stacktop);
while (th && th->text[0]) {
langs_num++;
th = th->next;
}
if (!th) return;
if (docp)
langs_num /= 3;
else
langs_num /= 2;
pop_empty_string = TRUE;
} else {
// use counts languages
langs_num = myatou(temp);
}
// zero languages?
if (!langs_num) return;
// initialize visible languages count
visible_langs_num = 0;
// allocate language struct
langs = (struct lang *)GlobalAlloc(GPTR, langs_num*sizeof(struct lang));
if (!langs) return;
// fill language struct
for (i = 0; i < langs_num; i++) {
if (popstring(temp)) { visible_langs_num = 0; break; }
langs[visible_langs_num].name = (TCHAR*) GlobalAlloc(GPTR, (lstrlen(temp)+1)*sizeof(TCHAR));
if (!langs[visible_langs_num].name) { visible_langs_num = 0; break; }
lstrcpy(langs[visible_langs_num].name, temp);
if (popstring(temp)) { visible_langs_num = 0; break; }
langs[visible_langs_num].id = (TCHAR*) GlobalAlloc(GPTR, (lstrlen(temp)+1)*sizeof(TCHAR));
if (!langs[visible_langs_num].id) { visible_langs_num = 0; break; }
lstrcpy(langs[visible_langs_num].id, temp);
if (docp)
{
if (popstring(temp)) { visible_langs_num = 0; break; }
langs[visible_langs_num].cp = myatou(temp);
}
// If Unicode, show everything.
#ifdef _UNICODE
visible_langs_num++;
#else
if (!docp || langs[visible_langs_num].cp == GetACP() || langs[visible_langs_num].cp == 0)
{
visible_langs_num++;
}
else
{
GlobalFree(langs[visible_langs_num].name);
GlobalFree(langs[visible_langs_num].id);
}
#endif
}
// pop the empty string to keep the stack clean
if (pop_empty_string) {
if (popstring(temp)) {
visible_langs_num = 0;
}
}
// start dialog
if (visible_langs_num > 1)
{
DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_DIALOG), 0, DialogProc);
}
else if (visible_langs_num == 0)
{
pushstring(_T(""));
}
else
{
pushstring(langs[0].id);
}
// free structs
for (i = 0; i < visible_langs_num; i++) {
if (langs[i].name) GlobalFree(langs[i].name);
if (langs[i].id) GlobalFree(langs[i].id);
}
GlobalFree(langs);
}
}
BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
g_hInstance=hInst;
return TRUE;
}