- BgImage improved a lot

- Added .onGUIEnd
- Some optimizations


git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@2542 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
kichik 2003-05-09 21:11:14 +00:00
parent 65806e3b4b
commit 26845a8b74
12 changed files with 724 additions and 193 deletions

View file

@ -2,128 +2,539 @@
#include <Mmsystem.h>
#include "../exdll/exdll.h"
int x, y;
char temp[MAX_PATH];
HBITMAP hBitmap;
#define NSISFunc(name) extern "C" void __declspec(dllexport) name(HWND hwndParent, int string_size, char *variables, stack_t **stacktop)
char szTemp[2048];
HWND hWndImage, hWndParent;
HINSTANCE g_hInstance;
enum {
MIL_DUMMY,
MIL_GRADIENT,
MIL_BITMAP,
MIL_TRANSPARENT_BITMAP,
MIL_TEXT
};
struct myImageList {
BYTE iType;
union {
HBITMAP hBitmap;
char *szText;
COLORREF cGradientFrom;
};
RECT rPos;
union {
COLORREF cTransparent;
COLORREF cTextColor;
COLORREF cGradientTo;
};
HFONT hFont;
BOOL bReady;
myImageList *next;
} bgBitmap;
unsigned int uWndWidth, uWndHeight;
void *oldProc;
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
int myatoi(char *s);
extern "C" void __declspec(dllexport) SetImage(HWND hwndParent, int string_size, char *variables, stack_t **stacktop);
COLORREF GetColor();
extern "C" void __declspec(dllexport) Init(HWND hwndParent, int string_size, char *variables, stack_t **stacktop) {
hWndParent = hwndParent;
BOOL bReturn;
if (!hwndParent) {
pushstring("can't find parent window");
return;
}
WNDCLASSEX wc = {
sizeof(WNDCLASSEX),
CS_VREDRAW|CS_HREDRAW,
WndProc,
0,
0,
g_hInstance,
0,//LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(103)),
0,
(HBRUSH)GetStockObject(WHITE_BRUSH),
0,
"NSISBGImage",
0
};
if (!RegisterClassEx(&wc)) {
pushstring("can't register class");
return;
}
hWndImage = CreateWindowEx(
WS_EX_TOOLWINDOW,
"NSISBGImage",
0,
WS_CLIPSIBLINGS|WS_POPUP,
0,
0,
0,
0,
0,
0,
g_hInstance,
0
);
if (!hWndImage) {
pushstring("can't create window");
return;
}
ShowWindow(hWndImage, SW_SHOW);
SetImage(hwndParent, string_size, variables, stacktop);
oldProc = (void *)SetWindowLong(hwndParent, GWL_WNDPROC, (long)WndProc);
}
extern "C" void __declspec(dllexport) SetImage(HWND hwndParent, int string_size, char *variables, stack_t **stacktop) {
NSISFunc(SetReturn) {
EXDLL_INIT();
popstring(temp);
if (!lstrcmp(temp, "/FILLSCREEN")) {
x = GetSystemMetrics(SM_CXSCREEN);
y = GetSystemMetrics(SM_CYSCREEN);
popstring(temp);
popstring(szTemp);
bReturn = !lstrcmpi(szTemp, "on");
}
static void my_pushstring(char *str)
{
stack_t *th;
if (!g_stacktop || !bReturn) return;
th=(stack_t*)GlobalAlloc(GPTR,sizeof(stack_t)+g_stringsize);
lstrcpyn(th->text,str,g_stringsize);
th->next=*g_stacktop;
*g_stacktop=th;
}
NSISFunc(SetBg) {
EXDLL_INIT();
bgBitmap.bReady = FALSE;
if (!hWndImage) {
hWndParent = hwndParent;
if (!hwndParent) {
my_pushstring("can't find parent window");
return;
}
WNDCLASSEX wc = {
sizeof(WNDCLASSEX),
CS_VREDRAW|CS_HREDRAW,
WndProc,
0,
0,
g_hInstance,
0,
LoadCursor(0, IDC_ARROW),
0,
0,
"NSISBGImage",
0
};
if (!RegisterClassEx(&wc)) {
my_pushstring("can't register class");
return;
}
hWndImage = CreateWindowEx(
WS_EX_TOOLWINDOW,
"NSISBGImage",
0,
WS_CLIPSIBLINGS|WS_POPUP,
0,
0,
0,
0,
0,
0,
g_hInstance,
0
);
if (!hWndImage) {
my_pushstring("can't create window");
return;
}
oldProc = (void *)SetWindowLong(hwndParent, GWL_WNDPROC, (long)WndProc);
}
else x = y = 0;
BITMAP bitmap;
if (bgBitmap.iType == MIL_BITMAP) DeleteObject(bgBitmap.hBitmap);
if (hBitmap) DeleteObject((HGDIOBJ)hBitmap);
hBitmap = (HBITMAP)LoadImage(0, temp, IMAGE_BITMAP, x, y, LR_LOADFROMFILE);
if (!hBitmap) {
pushstring("can't load bitmap");
unsigned int uScrWidth = GetSystemMetrics(SM_CXSCREEN);
unsigned int uScrHeight = GetSystemMetrics(SM_CYSCREEN);
bgBitmap.iType = MIL_BITMAP;
bgBitmap.rPos.right = 0;
bgBitmap.rPos.bottom = 0;
uWndWidth = uScrWidth;
uWndHeight = uScrHeight;
popstring(szTemp);
if (!lstrcmpi(szTemp, "/GRADIENT")) {
bgBitmap.cGradientFrom = GetColor();
bgBitmap.cGradientTo = GetColor();
bgBitmap.iType = MIL_GRADIENT;
goto done;
}
if (!lstrcmpi(szTemp, "/FILLSCREEN")) {
bgBitmap.rPos.right = uScrWidth;
bgBitmap.rPos.bottom = uScrHeight;
popstring(szTemp);
}
else if (!lstrcmpi(szTemp, "/TILED")) {
popstring(szTemp);
}
else {
uWndWidth = 0;
uWndHeight = 0;
}
BITMAP bBitmap;
bgBitmap.hBitmap = (HBITMAP)LoadImage(0, szTemp, IMAGE_BITMAP, bgBitmap.rPos.right, bgBitmap.rPos.bottom, LR_LOADFROMFILE);
if (!bgBitmap.hBitmap) {
my_pushstring("can't load bitmap");
return;
}
GetObject(hBitmap, sizeof(bitmap), (LPSTR)&bitmap);
x = x ? x : bitmap.bmWidth;
y = y ? y : bitmap.bmHeight;
if (!GetObject(bgBitmap.hBitmap, sizeof(bBitmap), (void *)&bBitmap)) {
my_pushstring("can't query bitmap size");
return;
}
if (!bgBitmap.rPos.right) {
bgBitmap.rPos.right = bBitmap.bmWidth;
bgBitmap.rPos.bottom = bBitmap.bmHeight;
}
if (!uWndWidth) {
uWndWidth = bBitmap.bmWidth;
uWndHeight = bBitmap.bmHeight;
}
done:
bgBitmap.bReady = TRUE;
if (hWndImage) {
SetWindowPos(
hWndImage,
hWndParent,
(GetSystemMetrics(SM_CXSCREEN)-x)/2,
(GetSystemMetrics(SM_CYSCREEN)-y)/2,
x,
y,
(uScrWidth-uWndWidth)/2,
(uScrHeight-uWndHeight)/2,
uWndWidth,
uWndHeight,
SWP_NOACTIVATE
);
RedrawWindow(hWndImage, 0, 0, RDW_INVALIDATE | RDW_UPDATENOW);
}
my_pushstring("success");
}
extern "C" void __declspec(dllexport) Destroy(HWND hwndParent, int string_size, char *variables, stack_t **stacktop) {
NSISFunc(AddImage) {
myImageList *newImg = (myImageList *)GlobalAlloc(GPTR, sizeof(myImageList));
if (!newImg) {
my_pushstring("memory allocation error");
return;
}
newImg->iType = MIL_BITMAP;
newImg->cTransparent = -1;
popstring(szTemp);
if (!lstrcmpi(szTemp, "/TRANSPARENT")) {
newImg->iType = MIL_TRANSPARENT_BITMAP;
newImg->cTransparent = GetColor();
popstring(szTemp);
}
newImg->hBitmap = (HBITMAP)LoadImage(0, szTemp, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
if (!newImg->hBitmap) {
my_pushstring("can't load bitmap");
return;
}
popstring(szTemp);
int iPosTemp = myatoi(szTemp);
if (iPosTemp < 0) iPosTemp = iPosTemp + (int)uWndWidth;
newImg->rPos.left = newImg->rPos.right = (unsigned int)iPosTemp;
popstring(szTemp);
iPosTemp = myatoi(szTemp);
if (iPosTemp < 0) iPosTemp = iPosTemp + (int)uWndHeight;
newImg->rPos.top = newImg->rPos.bottom = (unsigned int)iPosTemp;
BITMAP bBitmap;
if (!GetObject(newImg->hBitmap, sizeof(bBitmap), (void *)&bBitmap)) {
my_pushstring("can't query bitmap size");
return;
}
newImg->rPos.right += bBitmap.bmWidth;
newImg->rPos.bottom += bBitmap.bmHeight;
newImg->bReady = TRUE;
myImageList *img = &bgBitmap;
while (img->next) img = img->next;
img->next = newImg;
my_pushstring("success");
}
NSISFunc(AddText) {
myImageList *newImg = (myImageList *)GlobalAlloc(GPTR, sizeof(myImageList));
if (!newImg) {
my_pushstring("memory allocation error");
return;
}
newImg->iType = MIL_TEXT;
popstring(szTemp);
newImg->szText = (char *)GlobalAlloc(GPTR, lstrlen(szTemp)+1);
if (!newImg->szText) {
my_pushstring("memory allocation error");
return;
}
lstrcpy(newImg->szText, szTemp);
popstring(szTemp);
newImg->hFont = (HFONT)myatoi(szTemp);
newImg->cTextColor = GetColor();
popstring(szTemp);
int iPosTemp = myatoi(szTemp);
if (iPosTemp < 0) iPosTemp = iPosTemp + (int)uWndWidth;
newImg->rPos.left = (unsigned int)iPosTemp;
popstring(szTemp);
iPosTemp = myatoi(szTemp);
if (iPosTemp < 0) iPosTemp = iPosTemp + (int)uWndHeight;
newImg->rPos.top = (unsigned int)iPosTemp;
popstring(szTemp);
iPosTemp = myatoi(szTemp);
if (iPosTemp < 0) iPosTemp = iPosTemp + (int)uWndWidth;
newImg->rPos.right = (unsigned int)iPosTemp;
popstring(szTemp);
iPosTemp = myatoi(szTemp);
if (iPosTemp < 0) iPosTemp = iPosTemp + (int)uWndHeight;
newImg->rPos.bottom = (unsigned int)iPosTemp;
newImg->bReady = TRUE;
myImageList *img = &bgBitmap;
while (img->next) img = img->next;
img->next = newImg;
my_pushstring("success");
}
NSISFunc(Redraw) {
RedrawWindow(hWndImage, 0, 0, RDW_INVALIDATE | RDW_UPDATENOW);
ShowWindow(hWndImage, SW_SHOWNA);
}
NSISFunc(Clear) {
bgBitmap.bReady = FALSE;
myImageList *img = &bgBitmap;
while (img) {
switch (img->iType) {
case MIL_BITMAP:
case MIL_TRANSPARENT_BITMAP:
DeleteObject(img->hBitmap);
break;
case MIL_TEXT:
GlobalFree(img->szText);
break;
}
img = img->next;
if (img) GlobalFree(img);
}
bgBitmap.next = 0;
}
NSISFunc(Destroy) {
SetWindowLong(hWndParent, GWL_WNDPROC, (long)oldProc);
SendMessage(hWndImage, WM_CLOSE, 0, 0);
hWndImage = 0;
Clear(0, 0, 0, 0);
UnregisterClass("NSISBGImage", g_hInstance);
}
extern "C" void __declspec(dllexport) Sound(HWND hwndParent, int string_size, char *variables, stack_t **stacktop) {
DWORD flags = SND_FILENAME|SND_NODEFAULT;
NSISFunc(Sound) {
DWORD flags = SND_FILENAME|SND_NODEFAULT|SND_NOWAIT;
g_stacktop=stacktop;
popstring(temp);
if (lstrcmp(temp, "/WAIT"))
popstring(szTemp);
if (lstrcmpi(szTemp, "/WAIT"))
flags |= SND_ASYNC;
else
popstring(temp);
PlaySound(temp, 0, flags);
popstring(szTemp);
PlaySound(szTemp, 0, flags);
}
BOOL WINAPI _DllMainCRTStartup(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) {
g_hInstance=hInst;
return TRUE;
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
if (hwnd == hWndParent) {
if (message == WM_SIZE) {
ShowWindow(hWndImage, wParam == SIZE_MINIMIZED ? SW_HIDE : SW_SHOW);
}
if (message == WM_WINDOWPOSCHANGED) {
SetWindowPos(hWndImage, hWndParent, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
}
return CallWindowProc(
(long (__stdcall *)(HWND,unsigned int,unsigned int,long))oldProc,
hwnd,
message,
wParam,
lParam
);
}
switch (message) {
case WM_PAINT:
if (bgBitmap.bReady) {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
if (bgBitmap.iType == MIL_BITMAP) {
HDC cdc = CreateCompatibleDC(hdc);
SelectObject(cdc, bgBitmap.hBitmap);
for (unsigned int x = 0; x < uWndWidth; x += bgBitmap.rPos.right) {
for (unsigned int y = 0; y < uWndHeight; y += bgBitmap.rPos.bottom) {
BitBlt(hdc, x, y, bgBitmap.rPos.right, bgBitmap.rPos.bottom, cdc, 0, 0, SRCCOPY);
}
}
DeleteDC(cdc);
}
else {
int r = GetRValue(bgBitmap.cGradientFrom) << 10;
int g = GetGValue(bgBitmap.cGradientFrom) << 10;
int b = GetBValue(bgBitmap.cGradientFrom) << 10;
int dr = ((GetRValue(bgBitmap.cGradientTo) << 10) - r) / (int)uWndHeight * 4;
int dg = ((GetGValue(bgBitmap.cGradientTo) << 10) - g) / (int)uWndHeight * 4;
int db = ((GetBValue(bgBitmap.cGradientTo) << 10) - b) / (int)uWndHeight * 4;
RECT rect;
rect.left = 0;
rect.top = 0;
rect.right = uWndWidth;
rect.bottom = 4;
while (rect.top < (int)uWndHeight)
{
HBRUSH brush = CreateSolidBrush(RGB(r>>10,g>>10,b>>10));
FillRect(hdc, &rect, brush);
DeleteObject(brush);
rect.top+=4;
rect.bottom+=4;
r+=dr;
g+=dg;
b+=db;
}
}
myImageList *img = bgBitmap.next;
while (img) {
if (!img->bReady) break;
if (img->iType == MIL_TEXT) {
SetBkMode(hdc, TRANSPARENT);
HFONT hOldFont;
SetTextColor(hdc, img->cTextColor);
hOldFont = (HFONT)SelectObject(hdc, img->hFont);
DrawText(hdc, img->szText, -1, &img->rPos, DT_TOP | DT_LEFT | DT_NOPREFIX | DT_WORDBREAK);
SelectObject(hdc, hOldFont);
}
else if (img->iType == MIL_BITMAP) {
HDC cdc = CreateCompatibleDC(hdc);
SelectObject(cdc, img->hBitmap);
BitBlt(hdc, img->rPos.left, img->rPos.top, img->rPos.right - img->rPos.left, img->rPos.bottom - img->rPos.top, cdc, 0, 0, SRCCOPY);
DeleteDC(cdc);
}
else {
COLORREF cColor;
HBITMAP bmAndBack, bmAndObject, bmAndMem, bmSave;
HBITMAP bmBackOld, bmObjectOld, bmMemOld, bmSaveOld;
HDC hdcMem, hdcBack, hdcObject, hdcTemp, hdcSave;
POINT ptSize;
HBITMAP hBitmap = img->hBitmap;
hdcTemp = CreateCompatibleDC(hdc);
SelectObject(hdcTemp, hBitmap); // Select the bitmap
ptSize.x = img->rPos.right - img->rPos.left;
ptSize.y = img->rPos.bottom - img->rPos.top;
DPtoLP(hdcTemp, &ptSize, 1); // Convert from device to logical points
// Create some DCs to hold temporary data.
hdcBack = CreateCompatibleDC(hdc);
hdcObject = CreateCompatibleDC(hdc);
hdcMem = CreateCompatibleDC(hdc);
hdcSave = CreateCompatibleDC(hdc);
// Create a bitmap for each DC. DCs are required for a number of
// GDI functions.
// Monochrome DC
bmAndBack = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
// Monochrome DC
bmAndObject = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
bmAndMem = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);
bmSave = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);
// Each DC must select a bitmap object to store pixel data.
bmBackOld = (HBITMAP)SelectObject(hdcBack, bmAndBack);
bmObjectOld = (HBITMAP)SelectObject(hdcObject, bmAndObject);
bmMemOld = (HBITMAP)SelectObject(hdcMem, bmAndMem);
bmSaveOld = (HBITMAP)SelectObject(hdcSave, bmSave);
// Set proper mapping mode.
SetMapMode(hdcTemp, GetMapMode(hdc));
// Save the bitmap sent here, because it will be overwritten.
BitBlt(hdcSave, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY);
// Set the background color of the source DC to the color.
// contained in the parts of the bitmap that should be transparent
cColor = SetBkColor(hdcTemp, img->cTransparent);
// Create the object mask for the bitmap by performing a BitBlt
// from the source bitmap to a monochrome bitmap.
BitBlt(hdcObject, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0,
SRCCOPY);
// Set the background color of the source DC back to the original
// color.
SetBkColor(hdcTemp, cColor);
// Create the inverse of the object mask.
BitBlt(hdcBack, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0,
NOTSRCCOPY);
// Copy the background of the main DC to the destination.
BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdc, img->rPos.left, img->rPos.top,
SRCCOPY);
// Mask out the places where the bitmap will be placed.
BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, SRCAND);
// Mask out the transparent colored pixels on the bitmap.
BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, SRCAND);
// XOR the bitmap with the background on the destination DC.
BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT);
// Copy the destination to the screen.
BitBlt(hdc, img->rPos.left, img->rPos.top, ptSize.x, ptSize.y, hdcMem, 0, 0,
SRCCOPY);
// Place the original bitmap back into the bitmap sent here.
BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcSave, 0, 0, SRCCOPY);
// Delete the memory bitmaps.
DeleteObject(SelectObject(hdcBack, bmBackOld));
DeleteObject(SelectObject(hdcObject, bmObjectOld));
DeleteObject(SelectObject(hdcMem, bmMemOld));
DeleteObject(SelectObject(hdcSave, bmSaveOld));
// Delete the memory DCs.
DeleteDC(hdcMem);
DeleteDC(hdcBack);
DeleteDC(hdcObject);
DeleteDC(hdcSave);
DeleteDC(hdcTemp);
}
img = img->next;
}
EndPaint(hwnd, &ps);
}
break;
case WM_WINDOWPOSCHANGING:
{
LPWINDOWPOS wp = (LPWINDOWPOS) lParam;
wp->flags |= SWP_NOACTIVATE;
wp->hwndInsertAfter = hWndParent;
break;
}
case WM_CLOSE:
DestroyWindow(hWndImage);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
COLORREF GetColor() {
int iRed, iGreen, iBlue;
popstring(szTemp);
iRed = myatoi(szTemp);
popstring(szTemp);
iGreen = myatoi(szTemp);
popstring(szTemp);
iBlue = myatoi(szTemp);
return RGB(iRed, iGreen, iBlue);
}
int myatoi(char *s)
@ -171,48 +582,7 @@ int myatoi(char *s)
return (int)v;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
if (hWndImage && hwnd != hWndImage) {
if (message == WM_SIZE) {
ShowWindow(hWndImage, wParam == SIZE_MINIMIZED ? SW_HIDE : SW_SHOW);
}
if (message == WM_WINDOWPOSCHANGED) {
SetWindowPos(hWndImage, hWndParent, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
}
return CallWindowProc(
(long (__stdcall *)(HWND,unsigned int,unsigned int,long))oldProc,
hwnd,
message,
wParam,
lParam
);
}
switch (message) {
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
HDC cdc = CreateCompatibleDC(hdc);
HGDIOBJ hOldObject = SelectObject(cdc, hBitmap);
RECT cRect;
GetClientRect(hwnd, &cRect);
BitBlt(hdc, cRect.left, cRect.top, cRect.right - cRect.left, cRect.bottom - cRect.top, cdc, 0, 0, SRCCOPY);
SelectObject(cdc, hOldObject);
DeleteDC(cdc);
EndPaint(hwnd, &ps);
}
break;
case WM_WINDOWPOSCHANGING:
{
LPWINDOWPOS wp = (LPWINDOWPOS) lParam;
wp->flags |= SWP_NOACTIVATE;
wp->hwndInsertAfter = hWndParent;
break;
}
case WM_DESTROY:
SetWindowLong(hWndParent, GWL_WNDPROC, (long)oldProc);
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
BOOL WINAPI _DllMainCRTStartup(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) {
g_hInstance=hInst;
return TRUE;
}

View file

@ -4,7 +4,7 @@
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=BgImage - WIN32 RELEASE
CFG=BgImage - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
@ -13,11 +13,12 @@ CFG=BgImage - WIN32 RELEASE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "BgImage.mak" CFG="BgImage - WIN32 RELEASE"
!MESSAGE NMAKE /f "BgImage.mak" CFG="BgImage - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "BgImage - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "BgImage - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
@ -27,6 +28,9 @@ CFG=BgImage - WIN32 RELEASE
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "BgImage - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
@ -36,10 +40,11 @@ RSC=rc.exe
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Ignore_Export_Lib 1
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BgImage_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O1 /D "WIN32" /D "WIN32_LEAN_AND_MEAN" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BgImage_EXPORTS" /YX /FD /c
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "Banner_EXPORTS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "Banner_EXPORTS" /FAcs /FD /c
# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
@ -49,11 +54,41 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib winmm.lib gdi32.lib /nologo /entry:"_DllMainCRTStartup" /dll /machine:I386 /nodefaultlib /out:"../../Plugins/BgImage.dll" /opt:nowin98
# ADD LINK32 kernel32.lib user32.lib winmm.lib gdi32.lib /nologo /entry:"_DllMainCRTStartup" /dll /map /machine:I386 /nodefaultlib /out:"../../Plugins/BgImage.dll" /opt:nowin98
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "BgImage - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 1
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "Banner_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "Banner_EXPORTS" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib winmm.lib gdi32.lib /nologo /dll /map /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "BgImage - Win32 Release"
# Name "BgImage - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"

View file

@ -1,37 +1,91 @@
BgImage.DLL - NSIS extension DLL
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Displays an image behind the NSIS window.
Displays an image or a gradient with user defined texts and/or images behind the NSIS window.
Can also play WAVs.
Note
~~~~
See Example.nsi for a usage example.
All but the last used function (which should be Destroy) must use /NOUNLOAD so the image window won't be destroyed before it should. Therefore, this DLL requires NSIS 2.0a7 and above.
Usage
~~~~~
1) Call SetBg to set the background
2) Call AddText, or AddImage to add texts and images
3) Call Redraw to update the background window
4) Optional - repeat steps 2-3 to add more images
-or-
call Clear and repeat steps 1-3 for a completely new background.
5) Call Destroy when the background is no longer required (.onGUIEnd for example)
Notes
~~~~~
* All but the last used function (which should be Destroy) must use /NOUNLOAD so the image window won't be destroyed before it should.
* This plugin requires NSIS 2.0b4 and above.
* Do not call SetBg (which creates the window) from a section unless you're going to destroy it from a section.
* Always use /NOUNLOAD in .onInstSuccess and .onInstFailed. Failing to do so will cause the installer to crash.
This means you should not call Destroy from .onInstSuccess or .onInstFailed.
Available functions
~~~~~~~~~~~~~~
Init [/FILLSCREEN] path_to_bitmap
Create a new image window
SetBg [/FILLSCREEN|/TILED] path_to_bitmap
SetBg /GRADIENT R G B R G B
Sets the background and creates the window if necessary
Use /FILLSCREEN to make the image fill the screen
Use /TILED to set a tiled background
Use /GRADIENT to set a gradient background
If SetReturn on was called returns "success" on the stack
or an error string if there was an error
Do not use in .onInit!
SetImage [/FILLSCREEN] path_to_bitmap
Sets a new image to the current timage window
Use /FILLSCREEN to make the image fill the screen
Do not use in .onInit!
AddImage [/TRANSPARENT R G B] path_to_bitmap X Y
Adds an image to the background window at (X,Y)
Use /TRANSPARENT to make BgImage draw the image transparently
Define the transprent color using R G B
If SetReturn on was called returns "success" on the stack
or an error string if there was an error
AddText text font_handle R G B X Y X Y
Adds text to the background window
Use NSIS's CreateFont to create a font and pass it as font_handle
Use R G B to set the text color
The first X Y is for the top left corner of the text box
The second X Y is for the bottom right corner of the text box
If SetReturn on was called returns "success" on the stack
or an error string if there was an error
Clear
Clears all of the current background, images and texts
Destroy
Destroys the current image window
Destroys the current background window
Destroy calls Clear automatically
Sound [/WAIT] path_to_wav
Plays a wave file
Use /WAIT to wait for the sound to finish playing
SetReturn on|off
Enable return values from SetBg, AddImage and AddText
Default value is off because all of the possible errors
are either things you should handle when debugging your script
such as "can't load bitmap" or errors you can do nothing about
such as "memory allocation error"
Credits
~~~~~~~
Coded by Amir Szekely, aka KiCHiK
Modified by Ximon Eighteen, aka Sunjammer (08Feb2003) - Removed the window title bar
Ximon Eighteen, aka Sunjammer - Fixed window title bar issues
iceman_k - Text idea and original implmentation
Lajos Molnar, aka orfanik - Tile idea and original implmentation
Jason Reis - Coding help

View file

@ -4,23 +4,64 @@ OutFile "BgImage Test.exe"
XPStyle on
Section
!define DEBUG
!macro GetReturnValue
!ifdef DEBUG
Pop $R9
StrCmp $R9 success +2
DetailPrint "Error: $R9"
!endif
!macroend
Function .onGUIInit
# the plugins dir is automatically deleted when the installer exits
InitPluginsDir
File /oname=$PLUGINSDIR\modern.bmp "${NSISDIR}\Contrib\Icons\modern.bmp"
File /oname=$PLUGINSDIR\checks1.bmp "${NSISDIR}\Contrib\Icons\checks1.bmp"
# lets extract some bitmaps...
File /oname=$PLUGINSDIR\1.bmp "${NSISDIR}\Contrib\Icons\modern-wizard llama.bmp"
File /oname=$PLUGINSDIR\2.bmp "${NSISDIR}\Contrib\Icons\modern.bmp"
BgImage::Init /NOUNLOAD /FILLSCREEN $PLUGINSDIR\modern.bmp
!ifdef DEBUG
# turn return values on if in debug mode
BgImage::SetReturn /NOUNLOAD on
!endif
MessageBox MB_OK "Next image?"
# set the initial background for images to be drawn on
# we will use a gradient from drak green to dark red
BgImage::SetBg /NOUNLOAD /GRADIENT 0 0x80 0 0x80 0 0
!insertmacro GetReturnValue
# add an image @ (150,0)
BgImage::AddImage /NOUNLOAD $PLUGINSDIR\2.bmp 150 0
!insertmacro GetReturnValue
# add the same image only transparent (magenta wiped) @ (150,16)
BgImage::AddImage /NOUNLOAD /TRANSPARENT 255 0 255 $PLUGINSDIR\2.bmp 150 16
!insertmacro GetReturnValue
# create the font for the following text
CreateFont $R0 "Comic Sans MS" 50 700
# add a blue shadow for the text
BgImage::AddText /NOUNLOAD "Testing 1... 2... 3..." $R0 0 0 255 48 48 798 198
!insertmacro GetReturnValue
# add a green shadow for the text
BgImage::AddText /NOUNLOAD "Testing 1... 2... 3..." $R0 0 255 0 52 52 802 202
!insertmacro GetReturnValue
# add the text
BgImage::AddText /NOUNLOAD "Testing 1... 2... 3..." $R0 255 0 0 50 50 800 200
!insertmacro GetReturnValue
# show our creation to the world!
BgImage::Redraw /NOUNLOAD
# Refresh doesn't return any value
FunctionEnd
BgImage::SetImage /NOUNLOAD /FILLSCREEN $PLUGINSDIR\checks1.bmp
ShowInstDetails show
Section
# play some sounds
FindFirst $0 $1 $WINDIR\Media\*.wav
StrCmp $0 "" skipSound
moreSounds:
StrCmp $1 "" noMoreSounds
BgImage::Sound /NOUNLOAD /WAIT $WINDIR\Media\$1
# Sound doesn't return any value either
MessageBox MB_YESNO "Another sound?" IDNO noMoreSounds
FindNext $0 $1
Goto moreSounds
@ -29,5 +70,33 @@ Section
FindClose $0
skipSound:
# change the background image to Mike, tiled
BgImage::SetBg /NOUNLOAD /TILED $PLUGINSDIR\1.bmp
!insertmacro GetReturnValue
# we have to redraw to reflect the changes
BgImage::Redraw /NOUNLOAD
MessageBox MB_OK "Mike the llama"
# clear everything
BgImage::Clear /NOUNLOAD
# Clear doesn't return any value
# set another gradient
BgImage::SetBg /NOUNLOAD /GRADIENT 0xFF 0xFA 0xBA 0xAA 0xA5 0x65
!insertmacro GetReturnValue
# add some text
BgImage::AddText /NOUNLOAD "A Desert for Mike" $R0 0 0 0 50 50 800 150
!insertmacro GetReturnValue
# add mike as an image
BgImage::AddImage /NOUNLOAD $PLUGINSDIR\1.bmp 50 150
!insertmacro GetReturnValue
# again, we have to call redraw to reflect changes
BgImage::Redraw /NOUNLOAD
SectionEnd
Function .onGUIEnd
# Destroy must not have /NOUNLOAD so NSIS will be able to unload
# and delete BgImage before it exits
BgImage::Destroy
SectionEnd
# Destroy doesn't return any value
FunctionEnd

Binary file not shown.

View file

@ -1252,6 +1252,7 @@ int CEXEBuild::write_output(void)
if (resolve_call_int("uninstall callback","un.callbacks",ns_func.find("un.onUserAbort",0),&build_uninst.common.code_onUserAbort)) return PS_ERROR;
#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
if (resolve_call_int("uninstall callback","un.callbacks",ns_func.find("un.onGUIInit",0),&build_uninst.common.code_onGUIInit)) return PS_ERROR;
if (resolve_call_int("uninstall callback","un.callbacks",ns_func.find("un.onGUIEnd",0),&build_uninst.common.code_onGUIEnd)) return PS_ERROR;
#endif
#endif//NSIS_SUPPORT_CODECALLBACKS
@ -1275,6 +1276,7 @@ int CEXEBuild::write_output(void)
if (resolve_call_int("install callback",".callbacks",ns_func.find(".onVerifyInstDir",0),&build_header.code_onVerifyInstDir)) return PS_ERROR;
#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
if (resolve_call_int("install callback",".callbacks",ns_func.find(".onGUIInit",0),&build_header.common.code_onGUIInit)) return PS_ERROR;
if (resolve_call_int("install callback",".callbacks",ns_func.find(".onGUIEnd",0),&build_header.common.code_onGUIEnd)) return PS_ERROR;
if (resolve_call_int("install callback",".callbacks",ns_func.find(".onMouseOverSection",0),&build_header.code_onMouseOverSection)) return PS_ERROR;
#endif
#ifdef NSIS_CONFIG_COMPONENTPAGE

View file

@ -274,7 +274,6 @@ int NSISCALL ui_doinstall(void)
if (inst_cmnheader->bg_color1 != -1)
{
RECT vp;
extern int bg_color1, bg_color2, bg_textcolor;
extern LRESULT CALLBACK BG_WndProc(HWND, UINT, WPARAM, LPARAM);
wc.lpfnWndProc = BG_WndProc;
wc.hInstance = g_hInstance;
@ -284,10 +283,6 @@ int NSISCALL ui_doinstall(void)
if (!RegisterClass(&wc)) return 0;
bg_color1=inst_cmnheader->bg_color1;
bg_color2=inst_cmnheader->bg_color2;
bg_textcolor=inst_cmnheader->bg_textcolor;
SystemParametersInfo(SPI_GETWORKAREA, 0, &vp, 0);
m_bgwnd = CreateWindowEx(WS_EX_TOOLWINDOW,"_Nb",0,WS_POPUP,
@ -300,8 +295,10 @@ int NSISCALL ui_doinstall(void)
if (ExecuteCodeSegment(inst_cmnheader->code_onInit,NULL)) return 1;
set_language();
g_hwnd=NULL;
ShowWindow(m_bgwnd, SW_SHOW);
#endif//NSIS_SUPPORT_CODECALLBACKS
#ifdef NSIS_SUPPORT_BGBG
ShowWindow(m_bgwnd, SW_SHOW);
#endif//NSIS_SUPPORT_BGBG
#ifdef NSIS_CONFIG_LICENSEPAGE
{ // load richedit DLL
@ -325,7 +322,13 @@ int NSISCALL ui_doinstall(void)
}
#endif
return DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_INST+dlg_offset),0,DialogProc);
{
int ret=DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_INST+dlg_offset),0,DialogProc);
#if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_ENHANCEDUI_SUPPORT)
ExecuteCodeSegment(g_inst_cmnheader->code_onGUIEnd,NULL);
#endif
return ret;
}
}
#endif//NSIS_CONFIG_VISIBLE_SUPPORT
#ifdef NSIS_CONFIG_SILENT_SUPPORT
@ -414,7 +417,7 @@ BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
// Call leave function. If Abort used don't move to the next page.
if (m_delta==1) if (ExecuteCodeSegment(this_page->leavefunc,NULL)) return 1;
#endif
// if the last page was a custom page, wait for it to finish by itself.
// if it doesn't, it's a BAD plugin.
// plugins should react to WM_NOTIFY_OUTER_NEXT.
@ -445,9 +448,9 @@ nextPage:
if (g_flags.abort)
{
this_page->button_states|=16|4;
SendMessage(g_hwnd,DM_SETDEFID,IDCANCEL,0);
SendMessage(hwndDlg,DM_SETDEFID,IDCANCEL,0);
}
else SendMessage(g_hwnd,DM_SETDEFID,IDOK,0);
else SendMessage(hwndDlg,DM_SETDEFID,IDOK,0);
SetWindowLong(hwndtmp,GWL_STYLE,GetWindowLong(hwndtmp,GWL_STYLE)&~BS_DEFPUSHBUTTON);
ShowWindow(hwndtmp,this_page->button_states&SW_SHOWNA);// SW_HIDE = 0, SW_SHOWNA = 8
EnableWindow(hwndtmp,this_page->button_states&2);

View file

@ -8,7 +8,8 @@
#ifdef NSIS_SUPPORT_BGBG
int bg_color1, bg_color2, bg_textcolor;
#define c1 g_inst_cmnheader->bg_color1
#define c2 g_inst_cmnheader->bg_color2
LRESULT CALLBACK BG_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
@ -23,46 +24,43 @@ LRESULT CALLBACK BG_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
}
case WM_PAINT:
{
static PAINTSTRUCT ps;
PAINTSTRUCT ps;
HDC hdc=BeginPaint(hwnd,&ps);
RECT r;
int y,ry;
int ry;
GetClientRect(hwnd,&r);
// this portion by Drew Davidson, drewdavidson@mindspring.com
ry=r.bottom;
y=0; //r.top
// JF: made slower, reduced to 4 pixels high, because I like how it looks better/
while (y < r.bottom)
while (r.top < ry)
{
int rv,gv,bv;
RECT rect;
HBRUSH brush;
rv = (GetRValue(bg_color2) * y + GetRValue(bg_color1) * ry) / r.bottom;
gv = (GetGValue(bg_color2) * y + GetGValue(bg_color1) * ry) / r.bottom;
bv = (GetBValue(bg_color2) * y + GetBValue(bg_color1) * ry) / r.bottom;
rv = (GetRValue(c2) * r.top + GetRValue(c1) * (ry-r.top)) / ry;
gv = (GetGValue(c2) * r.top + GetGValue(c1) * (ry-r.top)) / ry;
bv = (GetBValue(c2) * r.top + GetBValue(c1) * (ry-r.top)) / ry;
brush = CreateSolidBrush(RGB(rv,gv,bv));
SetRect(&rect, 0 /*r.left*/, y, r.right, y+4);
// note that we don't need to do "SelectObject(hdc, brush)"
// because FillRect lets us specify the brush as a parameter.
FillRect(hdc, &rect, brush);
FillRect(hdc, &r, brush);
DeleteObject(brush);
ry-=4;
y+=4;
r.top+=4;
r.bottom+=4;
}
if (bg_textcolor != -1)
if (g_inst_cmnheader->bg_textcolor != -1)
{
HFONT newFont, oldFont;
newFont = CreateFont(40,0,0,0,FW_BOLD,TRUE,FALSE,FALSE,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,"Garamond");
if (newFont)
{
static char buf[256];
r.left+=16;
r.top+=8;
r.left=16;
r.top=8;
my_GetWindowText(hwnd,buf,sizeof(buf));
SetBkMode(hdc,TRANSPARENT);
SetTextColor(hdc,bg_textcolor);
SetTextColor(hdc,g_inst_cmnheader->bg_textcolor);
oldFont = SelectObject(hdc,newFont);
DrawText(hdc,buf,-1,&r,DT_TOP|DT_LEFT|DT_SINGLELINE|DT_NOPREFIX);
SelectObject(hdc,oldFont);

View file

@ -152,6 +152,10 @@ static int NSISCALL ExecuteEntry(entry *entry_)
int parm5 = entry_->offsets[5];
//char *var5 = g_usrvars[parm5]; // not used yet
int which = entry_->which;
// Saves 8 bytes
// HWND mainHwnd = g_hwnd;
// #define g_hwnd mainHwnd
parms = entry_->offsets;
@ -196,9 +200,8 @@ static int NSISCALL ExecuteEntry(entry *entry_)
case EW_SLEEP:
{
int x=process_string_fromparm_toint(0);
if (x < 1) x=1;
log_printf2("Sleep(%d)",x);
Sleep(x);
Sleep(min(x,1));
}
break;
case EW_BRINGTOFRONT:
@ -764,13 +767,13 @@ static int NSISCALL ExecuteEntry(entry *entry_)
RECT r;
HANDLE hImage;
HWND hwImage=GetDlgItem(g_hwnd, parm1);
GetWindowRect(hwImage, &r);
GetClientRect(hwImage, &r);
hImage=LoadImage(
0,
process_string_fromparm_tobuf(0x00),
IMAGE_BITMAP,
parm2?r.right-r.left:0,
parm2?r.bottom-r.top:0,
parm2?r.right:0,
parm2?r.bottom:0,
LR_LOADFROMFILE
);
DeleteObject((HGDIOBJ)SetWindowLong(hwImage,GWL_USERDATA,(LONG)hImage));

View file

@ -350,6 +350,7 @@ typedef struct
int code_onUserAbort;
#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
int code_onGUIInit;
int code_onGUIEnd;
#endif
#endif//NSIS_SUPPORT_CODECALLBACKS

View file

@ -9,7 +9,7 @@ extern void dopause(void);
// Adds the bitmap in filename using resource editor re as id id.
// If width or height are specified it will also make sure the bitmap is in that size
int update_bitmap(CResourceEditor* re, WORD id, char* filename, int width=0, int height=0);
int update_bitmap(CResourceEditor* re, WORD id, char* filename, int width=0, int height=0, int maxbpp=0);
// reads icon file filename and places its icons in the resource wIconId using resource editor re. Also updates icondata_size.
int replace_icon(CResourceEditor* re, WORD wIconId, char* filename);

View file

@ -16,10 +16,6 @@ NSIS
* all installer strings should be language strings
PLUGINS
* BGImage - crash when called from .onInstSuccess
-- Before NSIS 2 Final --
EXAMPLES