initial: nsAdvsplash plugin 1.0.0
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.{yml,yaml,json}]
|
||||
indent_size = 2
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.{cmd,bat,ps1}]
|
||||
end_of_line = crlf
|
||||
|
||||
[*.{nsi,nsh,sln,vcxproj,filters}]
|
||||
end_of_line = crlf
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
@@ -0,0 +1,52 @@
|
||||
# Normalizzazione line endings
|
||||
* text=auto eol=lf
|
||||
|
||||
# File di codice
|
||||
*.c text eol=lf
|
||||
*.cpp text eol=lf
|
||||
*.h text eol=lf
|
||||
*.hpp text eol=lf
|
||||
*.def text eol=lf
|
||||
*.py text eol=lf
|
||||
*.ps1 text eol=lf
|
||||
*.cmd text eol=crlf
|
||||
*.bat text eol=crlf
|
||||
|
||||
# NSIS
|
||||
*.nsi text eol=crlf
|
||||
*.nsh text eol=crlf
|
||||
|
||||
# Markdown / docs / config
|
||||
*.md text eol=lf
|
||||
*.yml text eol=lf
|
||||
*.yaml text eol=lf
|
||||
*.json text eol=lf
|
||||
*.txt text eol=lf
|
||||
*.xml text eol=lf
|
||||
|
||||
# Visual Studio (CRLF richiesto)
|
||||
*.sln text eol=crlf
|
||||
*.vcxproj text eol=crlf merge=union
|
||||
*.filters text eol=crlf merge=union
|
||||
*.rc binary
|
||||
*.rc2 binary
|
||||
|
||||
# Binari
|
||||
*.dll binary
|
||||
*.exe binary
|
||||
*.lib binary
|
||||
*.obj binary
|
||||
*.pdb binary
|
||||
*.zip binary
|
||||
*.7z binary
|
||||
*.png binary
|
||||
*.ico binary
|
||||
*.gif binary
|
||||
*.jpg binary
|
||||
*.jpeg binary
|
||||
*.bmp binary
|
||||
*.pdf binary
|
||||
|
||||
# Linguistic detection (GitHub Linguist / Gitea analogo)
|
||||
*.nsi linguist-language=NSIS
|
||||
*.nsh linguist-language=NSIS
|
||||
@@ -0,0 +1,76 @@
|
||||
name: Bug Report
|
||||
description: Segnala un bug riproducibile
|
||||
title: "[Bug]: "
|
||||
labels: ["bug", "triage"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Grazie per la segnalazione. Compila i campi sotto per aiutarci a riprodurre il problema.
|
||||
|
||||
- type: input
|
||||
id: plugin-version
|
||||
attributes:
|
||||
label: Versione plugin
|
||||
description: Contenuto del file VERSION o tag della release scaricata
|
||||
placeholder: "1.6.0"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: architecture
|
||||
attributes:
|
||||
label: Architettura DLL usata
|
||||
options:
|
||||
- x86-ansi
|
||||
- x86-unicode
|
||||
- amd64-unicode
|
||||
- non so / multiple
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: nsis-version
|
||||
attributes:
|
||||
label: Versione NSIS
|
||||
placeholder: "3.10"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: os
|
||||
attributes:
|
||||
label: Sistema operativo
|
||||
placeholder: "Windows 11 23H2 x64"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: repro
|
||||
attributes:
|
||||
label: Passi per riprodurre
|
||||
description: Script .nsi minimale che riproduce il problema
|
||||
render: nsis
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: expected
|
||||
attributes:
|
||||
label: Comportamento atteso
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: actual
|
||||
attributes:
|
||||
label: Comportamento osservato
|
||||
description: Includi messaggi di errore esatti, output del log NSIS, screenshot
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: additional
|
||||
attributes:
|
||||
label: Note aggiuntive
|
||||
description: Qualunque altra informazione utile (workaround tentati, ecc.)
|
||||
@@ -0,0 +1,8 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Domande generali
|
||||
url: https://gitea.emulab.it/Simone/nsis-plugin-nsadvsplash/issues?type=question
|
||||
about: Per domande di utilizzo che non sono bug, apri una issue con label "question"
|
||||
- name: Security
|
||||
url: https://gitea.emulab.it/Simone/nsis-plugin-nsadvsplash/security/advisories/new
|
||||
about: Segnala vulnerabilità di security in privato (non aprire issue pubbliche)
|
||||
@@ -0,0 +1,32 @@
|
||||
name: Feature Request
|
||||
description: Suggerisci una nuova funzionalità o miglioramento
|
||||
title: "[Feature]: "
|
||||
labels: ["enhancement"]
|
||||
body:
|
||||
- type: textarea
|
||||
id: problem
|
||||
attributes:
|
||||
label: Problema / Caso d'uso
|
||||
description: Quale problema vorresti risolvere? Quale workflow vuoi abilitare?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: proposal
|
||||
attributes:
|
||||
label: Proposta
|
||||
description: Come dovrebbe funzionare? Includi esempio di API/uso negli script NSIS se possibile.
|
||||
render: nsis
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: alternatives
|
||||
attributes:
|
||||
label: Alternative considerate
|
||||
description: Altri approcci che hai valutato e perché sono stati scartati
|
||||
|
||||
- type: textarea
|
||||
id: additional
|
||||
attributes:
|
||||
label: Note aggiuntive
|
||||
@@ -0,0 +1,31 @@
|
||||
## Descrizione
|
||||
|
||||
<!-- Descrivi cosa cambia questa PR e perché. Riferisci issue se applicabile (Closes #XXX). -->
|
||||
|
||||
## Tipo di Modifica
|
||||
|
||||
- [ ] Bug fix (modifica non breaking che risolve un problema)
|
||||
- [ ] Feature (modifica non breaking che aggiunge funzionalità)
|
||||
- [ ] Breaking change (fix o feature che rompe la compatibilità)
|
||||
- [ ] Documentazione
|
||||
- [ ] Build / CI
|
||||
|
||||
## Architetture Testate
|
||||
|
||||
- [ ] `x86-ansi`
|
||||
- [ ] `x86-unicode`
|
||||
- [ ] `amd64-unicode`
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] Build completa senza warning: `python build_plugin.py`
|
||||
- [ ] CHANGELOG.md aggiornato (sezione `[Unreleased]`)
|
||||
- [ ] README / docs aggiornati se l'API è cambiata
|
||||
- [ ] Esempi aggiornati se l'API è cambiata
|
||||
- [ ] Conventional Commits rispettato
|
||||
- [ ] Nessun file in `dist/` o `__pycache__/` committato
|
||||
- [ ] Self-review completata
|
||||
|
||||
## Note Aggiuntive
|
||||
|
||||
<!-- Eventuali considerazioni per i reviewer, screenshot, output di test, ecc. -->
|
||||
@@ -0,0 +1,66 @@
|
||||
# Build (GitHub) — pipeline CI primaria
|
||||
#
|
||||
# Strategia hosting:
|
||||
# - Repo primario su Gitea (push iniziale)
|
||||
# - Push mirror automatico Gitea -> GitHub
|
||||
# - GitHub esegue TUTTA la CI (Gitea non esegue Actions)
|
||||
#
|
||||
# Trigger:
|
||||
# - push su main (incluso quello propagato dal mirror Gitea)
|
||||
# - PR aperte su GitHub
|
||||
# - run manuale via UI
|
||||
|
||||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- 'docs/**'
|
||||
- 'examples/**'
|
||||
pull_request:
|
||||
branches: [main]
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
config: [x86-ansi, x86-unicode, x64-unicode]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
|
||||
- name: Setup MSBuild
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
|
||||
- name: Read VERSION
|
||||
id: version
|
||||
shell: pwsh
|
||||
run: |
|
||||
$v = (Get-Content VERSION -Raw).Trim()
|
||||
"version=$v" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
|
||||
|
||||
- name: Build ${{ matrix.config }}
|
||||
run: python build_plugin.py --config ${{ matrix.config }} --verbosity minimal
|
||||
|
||||
- name: Upload DLL
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ github.event.repository.name }}-${{ steps.version.outputs.version }}-${{ matrix.config }}
|
||||
path: dist/**
|
||||
if-no-files-found: error
|
||||
retention-days: 30
|
||||
@@ -0,0 +1,99 @@
|
||||
# Release (GitHub) — pipeline release primaria
|
||||
#
|
||||
# Triggerata quando un tag v* viene propagato dal mirror Gitea.
|
||||
# Costruisce gli artifact per tutte le architetture e crea la GitHub Release.
|
||||
|
||||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags: ['v*']
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: 'Tag versione (es. v1.7.0)'
|
||||
required: true
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
config: [x86-ansi, x86-unicode, x64-unicode]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
|
||||
- uses: microsoft/setup-msbuild@v2
|
||||
|
||||
- name: Build ${{ matrix.config }}
|
||||
run: python build_plugin.py --config ${{ matrix.config }}
|
||||
|
||||
- name: Determine version & arch
|
||||
id: meta
|
||||
shell: pwsh
|
||||
run: |
|
||||
$tag = "${{ github.ref_name }}"
|
||||
if ([string]::IsNullOrEmpty($tag) -or $tag -eq "main") { $tag = "${{ inputs.tag }}" }
|
||||
$v = $tag -replace '^v',''
|
||||
$map = @{ 'x86-ansi' = 'x86-ansi'; 'x86-unicode' = 'x86-unicode'; 'x64-unicode' = 'amd64-unicode' }
|
||||
$dir = $map['${{ matrix.config }}']
|
||||
echo "version=$v" >> $env:GITHUB_OUTPUT
|
||||
echo "tag=$tag" >> $env:GITHUB_OUTPUT
|
||||
echo "dir=$dir" >> $env:GITHUB_OUTPUT
|
||||
|
||||
- name: Package
|
||||
shell: pwsh
|
||||
run: |
|
||||
$name = "${{ github.event.repository.name }}-${{ steps.meta.outputs.version }}-${{ steps.meta.outputs.dir }}"
|
||||
$stage = "stage/$name"
|
||||
New-Item -ItemType Directory -Force -Path $stage | Out-Null
|
||||
Copy-Item "dist/${{ steps.meta.outputs.dir }}/*" $stage -Recurse
|
||||
Copy-Item README.md, LICENSE, VERSION, CHANGELOG.md $stage
|
||||
if (Test-Path "include") { Copy-Item "include" $stage -Recurse }
|
||||
if (Test-Path "examples") { Copy-Item "examples" $stage -Recurse }
|
||||
Compress-Archive -Path "$stage/*" -DestinationPath "$name.zip" -Force
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: pkg-${{ matrix.config }}
|
||||
path: '*.zip'
|
||||
|
||||
publish:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: artifacts
|
||||
merge-multiple: true
|
||||
|
||||
- name: SHA256SUMS
|
||||
run: |
|
||||
cd artifacts
|
||||
sha256sum *.zip > SHA256SUMS.txt
|
||||
cat SHA256SUMS.txt
|
||||
|
||||
- name: Create GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: |
|
||||
artifacts/*.zip
|
||||
artifacts/SHA256SUMS.txt
|
||||
generate_release_notes: true
|
||||
body: |
|
||||
**Repository primario**: vedi link Gitea nel README.
|
||||
|
||||
Il mirror GitHub è generato automaticamente dal repo Gitea (sorgente di verità).
|
||||
Per issue e PR aprire ticket sul repository primario Gitea.
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
# Build output (src/ subdirs only — dist/ is tracked, contains pre-built DLLs)
|
||||
bin/
|
||||
obj/
|
||||
Build/
|
||||
build/
|
||||
|
||||
# Visual Studio
|
||||
*.user
|
||||
*.suo
|
||||
*.ncb
|
||||
*.sdf
|
||||
.vs/
|
||||
ipch/
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
*.opendb
|
||||
*.aps
|
||||
*.tlog
|
||||
*.idb
|
||||
*.pdb
|
||||
*.ilk
|
||||
*.exp
|
||||
*.lib
|
||||
*.obj
|
||||
|
||||
# Python
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.pyo
|
||||
.pytest_cache/
|
||||
*.egg-info/
|
||||
.venv/
|
||||
venv/
|
||||
|
||||
# Editor / IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# OS
|
||||
Thumbs.db
|
||||
desktop.ini
|
||||
.DS_Store
|
||||
|
||||
# NSIS
|
||||
*.nsh.bak
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
.logs/
|
||||
|
||||
# Sensitive
|
||||
.env
|
||||
.env.local
|
||||
*.pem
|
||||
*.key
|
||||
|
||||
# Migration/automation scripts (temporary, contain tokens — never commit)
|
||||
tools/t*.py
|
||||
tools/check_*.py
|
||||
tools/legacy/
|
||||
@@ -0,0 +1,26 @@
|
||||
# Changelog
|
||||
|
||||
Tutte le modifiche rilevanti a questo progetto sono documentate in questo file.
|
||||
|
||||
Il formato segue [Keep a Changelog](https://keepachangelog.com/it/1.0.0/),
|
||||
e il progetto aderisce al [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [1.0.1] — 2026-04-29
|
||||
|
||||
### Changed
|
||||
- Build script completamente riscritto: Colors, Spinner, BuildConfig, build parallelo con ThreadPoolExecutor, CPU info, output colorato OK/FAIL
|
||||
- CI: rimosso flag `--verbose` (non esistente) in favore di `--verbosity minimal`
|
||||
|
||||
## [1.0.0] — 2026-04-29
|
||||
|
||||
### Added
|
||||
- Prima release come repository indipendente
|
||||
- Build script unificato (`build_plugin.py`) con CLI canonica
|
||||
- CI/CD via GitHub Actions (mirror automatico Gitea → GitHub)
|
||||
- Documentazione completa (README, CONTRIBUTING, SECURITY)
|
||||
|
||||
[Unreleased]: https://gitea.emulab.it/Simone/nsis-plugin-nsadvsplash/compare/v1.0.1...HEAD
|
||||
[1.0.1]: https://gitea.emulab.it/Simone/nsis-plugin-nsadvsplash/compare/v1.0.0...v1.0.1
|
||||
[1.0.0]: https://gitea.emulab.it/Simone/nsis-plugin-nsadvsplash/releases/tag/v1.0.0
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
# Contribuire a nsAdvsplash
|
||||
|
||||
Grazie per il tuo interesse a contribuire!
|
||||
|
||||
> Repository primario: [https://gitea.emulab.it/Simone/nsis-plugin-nsadvsplash](https://gitea.emulab.it/Simone/nsis-plugin-nsadvsplash)
|
||||
> Mirror GitHub: [https://github.com/systempal/nsis-plugin-nsadvsplash](https://github.com/systempal/nsis-plugin-nsadvsplash) (read-only — apri PR su Gitea)
|
||||
|
||||
## Prerequisiti
|
||||
|
||||
| Strumento | Versione | Note |
|
||||
|-----------|----------|------|
|
||||
| Visual Studio | 2022 / 2026 | Workload: Desktop development with C++ (toolset v143/v145) |
|
||||
| Python | 3.7+ | Per `build_plugin.py` |
|
||||
| Git | 2.30+ | Con supporto submoduli se applicabile |
|
||||
|
||||
## Quick Start
|
||||
|
||||
```powershell
|
||||
git clone https://gitea.emulab.it/Simone/nsis-plugin-nsadvsplash.git
|
||||
cd nsis-plugin-nsadvsplash
|
||||
python build_plugin.py
|
||||
```
|
||||
|
||||
Output in `dist/{x86-ansi,x86-unicode,amd64-unicode}/`.
|
||||
|
||||
## Workflow Sviluppo
|
||||
|
||||
### 1. Branch
|
||||
|
||||
```powershell
|
||||
git checkout -b feat/nome-feature # nuova feature
|
||||
git checkout -b fix/descrizione-bug # bugfix
|
||||
git checkout -b docs/aggiornamento # solo doc
|
||||
git checkout -b chore/manutenzione # build, dipendenze
|
||||
```
|
||||
|
||||
### 2. Commit
|
||||
|
||||
Segui [Conventional Commits](https://www.conventionalcommits.org/it/v1.0.0/):
|
||||
|
||||
```
|
||||
feat: aggiunge supporto per formato XYZ
|
||||
fix: corregge crash su Windows 11 ARM
|
||||
docs: aggiorna esempio di utilizzo
|
||||
chore: aggiorna toolset MSVC
|
||||
refactor: estrae logica parsing in funzione separata
|
||||
test: aggiunge test per edge case
|
||||
build: aggiorna script di build
|
||||
ci: aggiorna workflow GitHub Actions
|
||||
```
|
||||
|
||||
Breaking changes:
|
||||
|
||||
```
|
||||
feat!: rinomina API Foo() in Bar()
|
||||
|
||||
BREAKING CHANGE: Foo() rinominata in Bar(); aggiornare tutti i chiamanti.
|
||||
```
|
||||
|
||||
### 3. Pull Request
|
||||
|
||||
PR aperte verso il branch `main` su Gitea. Verifica:
|
||||
|
||||
- [ ] Build completa senza warning per tutte le architetture: `python build_plugin.py`
|
||||
- [ ] Esempi aggiornati se cambia l'API
|
||||
- [ ] `CHANGELOG.md` aggiornato (sezione `[Unreleased]`)
|
||||
- [ ] Documentazione aggiornata (README, docs/API.md se esiste)
|
||||
- [ ] Conventional Commits rispettato
|
||||
- [ ] Nessun file in `dist/` o `__pycache__/` committato
|
||||
|
||||
## Build Script
|
||||
|
||||
```
|
||||
python build_plugin.py [opzioni]
|
||||
```
|
||||
|
||||
| Opzione | Default | Descrizione |
|
||||
|---------|---------|-------------|
|
||||
| `--config` | `all` | Architettura: `x86-ansi`, `x86-unicode`, `x64-unicode`, `all` |
|
||||
| `--toolset` | `auto` | Visual Studio: `2022`, `2026`, `auto` (rileva il più recente) |
|
||||
| `--jobs` | numero CPU | Thread paralleli per la build |
|
||||
| `--clean` | false | Pulisce `dist/` prima di compilare |
|
||||
| `--install-dir` | none | Copia DLL anche in `<dir>/{arch}/` (es. NSIS plugin folder) |
|
||||
| `--verbose` | false | Output dettagliato (mostra comandi MSBuild) |
|
||||
|
||||
Exit codes:
|
||||
- `0` — Successo
|
||||
- `1` — Errore di build
|
||||
- `2` — Prerequisiti mancanti
|
||||
- `3` — Argomenti invalidi
|
||||
|
||||
## Release Workflow
|
||||
|
||||
Le release sono automatiche via tag Git:
|
||||
|
||||
```powershell
|
||||
# 1. Aggiorna VERSION e CHANGELOG.md
|
||||
echo "1.7.0" > VERSION
|
||||
# (modifica CHANGELOG.md spostando entry da [Unreleased] a [1.7.0])
|
||||
|
||||
# 2. Commit
|
||||
git add VERSION CHANGELOG.md
|
||||
git commit -m "chore(release): v1.7.0"
|
||||
|
||||
# 3. Tag annotato
|
||||
git tag -a v1.7.0 -m "Release v1.7.0"
|
||||
|
||||
# 4. Push
|
||||
git push origin main
|
||||
git push origin v1.7.0
|
||||
```
|
||||
|
||||
Il workflow `.github/workflows/release.yml` compilerà tutte le architetture
|
||||
e creerà la release su Gitea con gli artifact ZIP allegati. Il mirror GitHub
|
||||
riceverà automaticamente il tag.
|
||||
|
||||
## Code Style
|
||||
|
||||
- C/C++: stile coerente con il file modificato
|
||||
- Python: PEP 8 (4 spazi indent, line length flessibile)
|
||||
- Header file: `#include` ordinati: stdlib → Win32 → progetto
|
||||
- Encoding: UTF-8 senza BOM (eccetto `.rc` che richiede UTF-16 LE)
|
||||
- Line endings: LF in repo (`.gitattributes` normalizza)
|
||||
|
||||
## Reporting Bug
|
||||
|
||||
Apri una [issue](https://gitea.emulab.it/Simone/nsis-plugin-nsadvsplash/issues/new) usando il template "Bug Report".
|
||||
Includi:
|
||||
- Versione plugin e architettura DLL usata
|
||||
- Versione NSIS
|
||||
- Sistema operativo
|
||||
- Script `.nsi` minimale che riproduce il problema
|
||||
- Output / errore esatto
|
||||
|
||||
## Domande
|
||||
|
||||
Per domande generali, apri una [issue](https://gitea.emulab.it/Simone/nsis-plugin-nsadvsplash/issues) con label `question`.
|
||||
@@ -0,0 +1,21 @@
|
||||
zlib License
|
||||
|
||||
Copyright (c) 2026 Simone
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
@@ -0,0 +1,137 @@
|
||||
# NewAdvSplash NSIS Plugin
|
||||
|
||||
**Personal modified version**
|
||||
|
||||
---
|
||||
|
||||
## Original Description
|
||||
|
||||
NewAdvSplash.dll - plug-in that lets you throw up a splash screen in NSIS installers with fading effects (win2k/xp) and transparency. At the same time can play wav-mp3 sound file.
|
||||
|
||||
## Usage
|
||||
|
||||
### 1) Show splash screen
|
||||
|
||||
```nsis
|
||||
newadvsplash::show [/NOUNLOAD] Delay FadeIn FadeOut KeyColor [/BANNER] [/PASSIVE] [/NOCANCEL] FileName
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
- `Delay` - time (milliseconds) to show image
|
||||
- `FadeIn` - time to show the fadein scene
|
||||
- `FadeOut` - time to show the fadeout scene
|
||||
- `KeyColor` - color used for transparency, could be any RGB value (for ex. R=255 G=100 B=16 -> KeyColor=0xFF6410). Use KeyColor=-1 if there is no transparent color at your image. If KeyColor=-2 and image type is gif, plug-in attempts to extract transparency color value from the file header. For gif images transparency on the static background works even if KeyColor=-1.
|
||||
- `/BANNER` - returns control to installer immediately after plug-in activation. Not depends on installer page - parent window NULL.
|
||||
- `/NOCANCEL` - disables 'exit on user click' default behaviour.
|
||||
- `/PASSIVE` - not forces splash window to foreground.
|
||||
- `FileName` - splash image filename (with extension!). Bmp, gif and jpg image types are supported.
|
||||
|
||||
**Examples:**
|
||||
|
||||
```nsis
|
||||
newadvsplash::show 3000 0 0 -2 "$PLUGINSDIR\catch.gif"
|
||||
```
|
||||
|
||||
```nsis
|
||||
newadvsplash::show /NOUNLOAD 1000 600 400 0xFF6410 /BANNER "$TEMP\spltmp.bmp"
|
||||
```
|
||||
|
||||
Use /NOUNLOAD with /BANNER key - this case plug-in not waits for the end of 'show' and returns control to installer. If used in .onInit function, /BANNER key requires 'ShowWindow $HWNDPARENT 2' in .onGUIInit
|
||||
|
||||
### 2) Stop splash
|
||||
|
||||
```nsis
|
||||
newadvsplash::stop [/WAIT | /FADEOUT]
|
||||
```
|
||||
|
||||
- Without options terminates banner.
|
||||
- With `/WAIT` option waits for the end.
|
||||
- With `/FADEOUT` option forces banner close with fade out effect ('Delay' -> 0).
|
||||
|
||||
### 3) Play sound
|
||||
|
||||
```nsis
|
||||
newadvsplash::play /NOUNLOAD [/LOOP] FileName
|
||||
```
|
||||
|
||||
- `FileName` - sound filename to play (with extension, wav, mp3 ...).
|
||||
- Empty Filename string "" stops sound.
|
||||
|
||||
**Example:**
|
||||
|
||||
```nsis
|
||||
newadvsplash::play /NOUNLOAD /LOOP "$PLUGINSDIR\snd.mp3"
|
||||
newadvsplash::show 2000 1000 500 -1 "$PLUGINSDIR\iamfat.jpg"
|
||||
```
|
||||
|
||||
### 4) Get window handle
|
||||
|
||||
```nsis
|
||||
newadvsplash::hwnd /NOUNLOAD
|
||||
Pop $0 ; $0 is window handle now
|
||||
```
|
||||
|
||||
## Compatibility
|
||||
|
||||
- Basic - Win95 and later.
|
||||
- Fadein/fadeout - win2k/winxp.
|
||||
|
||||
## Credits
|
||||
|
||||
- Original code - Justin
|
||||
- Converted to a plugin DLL by Amir Szekely (kichik)
|
||||
- Fading and transparency by Nik Medved (brainsucker)
|
||||
- Gif and jpeg support, /BANNER and /CANCEL, mp3 support - Takhir Bedertdinov
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Differences in the Personal Version
|
||||
|
||||
### New supported architecture: x64 (amd64-unicode)
|
||||
|
||||
The original supported only:
|
||||
- x86-ansi (Plugins\newadvsplash.dll)
|
||||
- x86-unicode (Unicode\plugins\newadvsplash.dll)
|
||||
|
||||
The personal version adds support for:
|
||||
- **amd64-unicode** (x64)
|
||||
|
||||
### Added Files
|
||||
|
||||
- `build_plugin.py` - Python script to compile the plugin for all architectures
|
||||
- `src/exdll.h` - Header for the NSIS extern DLL API
|
||||
- `src/NewAdvSplash.vcxproj` - Visual Studio project updated for VS2022 and x64
|
||||
|
||||
### Removed Files
|
||||
|
||||
Pre-compiled DLL files have been removed from the distribution as they are generated by the build:
|
||||
|
||||
- `Plugins/newadvsplash.dll`
|
||||
- `Unicode/plugins/newadvsplash.dll`
|
||||
|
||||
### Build
|
||||
|
||||
```cmd
|
||||
cd nsAdvsplash
|
||||
python build_plugin.py
|
||||
```
|
||||
|
||||
DLLs are copied to `dist/{platform}/newadvsplash.dll`.
|
||||
|
||||
### Build Options
|
||||
|
||||
```powershell
|
||||
python build_plugin.py --config x86-unicode # Single architecture (x86-ansi|x86-unicode|x64-unicode|all)
|
||||
python build_plugin.py --vs-version 2026 # Specific VS version (2022|2026|auto)
|
||||
python build_plugin.py --clean # Clean dist/ before build
|
||||
python build_plugin.py --install-dir "C:\NSIS\Plugins" # Copy to additional NSIS directory
|
||||
python build_plugin.py --verbosity minimal # MSBuild verbosity (quiet|minimal|normal|detailed|diagnostic)
|
||||
```
|
||||
|
||||
### Functional Changes
|
||||
|
||||
No functional changes compared to the original. Modifications are limited to the build infrastructure and x64 support.
|
||||
|
||||
---
|
||||
|
||||
*See [README_IT.md](README_IT.md) for the Italian version.*
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
# NewAdvSplash NSIS Plugin
|
||||
|
||||
**Versione personale modificata**
|
||||
|
||||
---
|
||||
|
||||
## Descrizione Originale
|
||||
|
||||
NewAdvSplash.dll - plug-in che permette di visualizzare uno splash screen negli installer NSIS con effetti di dissolvenza (win2k/xp) e trasparenza. Può contemporaneamente riprodurre file audio wav/mp3.
|
||||
|
||||
## Utilizzo
|
||||
|
||||
### 1) Mostra splash screen
|
||||
|
||||
```nsis
|
||||
newadvsplash::show [/NOUNLOAD] Delay FadeIn FadeOut KeyColor [/BANNER] [/PASSIVE] [/NOCANCEL] FileName
|
||||
```
|
||||
|
||||
**Parametri:**
|
||||
- `Delay` - tempo (millisecondi) di visualizzazione dell'immagine
|
||||
- `FadeIn` - tempo per la scena di fade in
|
||||
- `FadeOut` - tempo per la scena di fade out
|
||||
- `KeyColor` - colore usato per la trasparenza, può essere qualsiasi valore RGB (es. R=255 G=100 B=16 -> KeyColor=0xFF6410). Usare KeyColor=-1 se non c'è colore trasparente. Se KeyColor=-2 e il tipo è gif, il plug-in tenta di estrarre il colore di trasparenza dall'header del file.
|
||||
- `/BANNER` - restituisce il controllo all'installer subito dopo l'attivazione del plug-in.
|
||||
- `/NOCANCEL` - disabilita il comportamento default 'exit on user click'.
|
||||
- `/PASSIVE` - non forza la finestra splash in primo piano.
|
||||
- `FileName` - nome file immagine splash (con estensione!). Tipi supportati: Bmp, gif e jpg.
|
||||
|
||||
**Esempi:**
|
||||
|
||||
```nsis
|
||||
newadvsplash::show 3000 0 0 -2 "$PLUGINSDIR\catch.gif"
|
||||
```
|
||||
|
||||
```nsis
|
||||
newadvsplash::show /NOUNLOAD 1000 600 400 0xFF6410 /BANNER "$TEMP\spltmp.bmp"
|
||||
```
|
||||
|
||||
### 2) Ferma splash
|
||||
|
||||
```nsis
|
||||
newadvsplash::stop [/WAIT | /FADEOUT]
|
||||
```
|
||||
|
||||
- Senza opzioni termina il banner.
|
||||
- Con `/WAIT` attende la fine.
|
||||
- Con `/FADEOUT` forza la chiusura con effetto fade out.
|
||||
|
||||
### 3) Riproduci audio
|
||||
|
||||
```nsis
|
||||
newadvsplash::play /NOUNLOAD [/LOOP] FileName
|
||||
```
|
||||
|
||||
- `FileName` - file audio da riprodurre (con estensione, wav, mp3...).
|
||||
- Stringa vuota "" ferma l'audio.
|
||||
|
||||
### 4) Ottieni handle finestra
|
||||
|
||||
```nsis
|
||||
newadvsplash::hwnd /NOUNLOAD
|
||||
Pop $0 ; $0 è ora l'handle della finestra
|
||||
```
|
||||
|
||||
## Compatibilità
|
||||
|
||||
- Base - Win95 e successivi.
|
||||
- Fadein/fadeout - win2k/winxp.
|
||||
|
||||
## Crediti
|
||||
|
||||
- Codice originale - Justin
|
||||
- Convertito in plugin DLL da Amir Szekely (kichik)
|
||||
- Dissolvenza e trasparenza di Nik Medved (brainsucker)
|
||||
- Supporto gif e jpeg, /BANNER e /CANCEL, supporto mp3 - Takhir Bedertdinov
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Differenze nella versione personale
|
||||
|
||||
### Nuova architettura supportata: x64 (amd64-unicode)
|
||||
|
||||
L'originale supportava solo:
|
||||
- x86-ansi (Plugins\newadvsplash.dll)
|
||||
- x86-unicode (Unicode\plugins\newadvsplash.dll)
|
||||
|
||||
La versione personale aggiunge il supporto per:
|
||||
- **amd64-unicode** (x64)
|
||||
|
||||
### File aggiunti
|
||||
|
||||
- `build_plugin.py` - Script Python per compilare il plugin per tutte le architetture
|
||||
- `src/exdll.h` - Header per l'API NSIS extern DLL
|
||||
- `src/NewAdvSplash.vcxproj` - Progetto Visual Studio aggiornato per VS2022 e x64
|
||||
|
||||
### File rimossi
|
||||
|
||||
I file DLL precompilati sono stati rimossi dalla distribuzione in quanto vengono generati dalla compilazione:
|
||||
|
||||
- `Plugins/newadvsplash.dll`
|
||||
- `Unicode/plugins/newadvsplash.dll`
|
||||
|
||||
### Compilazione
|
||||
|
||||
```cmd
|
||||
cd nsAdvsplash
|
||||
python build_plugin.py
|
||||
```
|
||||
|
||||
I DLL vengono copiati in `dist/{platform}/newadvsplash.dll`.
|
||||
|
||||
### Opzioni build
|
||||
|
||||
```powershell
|
||||
python build_plugin.py --config x86-unicode # Solo un'architettura (x86-ansi|x86-unicode|x64-unicode|all)
|
||||
python build_plugin.py --vs-version 2026 # Versione VS specifica (2022|2026|auto)
|
||||
python build_plugin.py --clean # Pulizia dist/ prima della build
|
||||
python build_plugin.py --install-dir "C:\NSIS\Plugins" # Copia in directory NSIS aggiuntiva
|
||||
python build_plugin.py --verbosity minimal # Verbosità MSBuild (quiet|minimal|normal|detailed|diagnostic)
|
||||
```
|
||||
|
||||
### Modifiche funzionali
|
||||
|
||||
Nessuna modifica funzionale rispetto all'originale. Le modifiche riguardano solo l'infrastruttura di build e il supporto x64.
|
||||
|
||||
---
|
||||
|
||||
*See [README.md](README.md) for the English version.*
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
# Security Policy
|
||||
|
||||
## Versioni Supportate
|
||||
|
||||
Solo l'ultima versione minor riceve fix di security.
|
||||
|
||||
| Versione | Supporto |
|
||||
|----------|----------|
|
||||
| Latest minor (es. 1.0.0) | ✅ |
|
||||
| Versioni precedenti | ❌ |
|
||||
|
||||
## Reporting di una Vulnerabilità
|
||||
|
||||
**Non aprire issue pubbliche per vulnerabilità di security.**
|
||||
|
||||
Per segnalare una vulnerabilità:
|
||||
|
||||
1. **Preferito**: usa la funzione [Security Advisory privato](https://gitea.emulab.it/Simone/nsis-plugin-nsadvsplash/security/advisories/new) di Gitea
|
||||
2. **Alternativa**: invia email a `security@example.com` (sostituire con email reale prima del primo release)
|
||||
|
||||
Includi:
|
||||
- Descrizione della vulnerabilità
|
||||
- Passi per riprodurla
|
||||
- Versione/i affette
|
||||
- Possibile mitigazione (se nota)
|
||||
|
||||
## Tempo di Risposta
|
||||
|
||||
- Acknowledgment iniziale: entro 7 giorni
|
||||
- Valutazione: entro 14 giorni
|
||||
- Patch (se confermata): tempistiche dipendono dalla severità
|
||||
|
||||
## Hardening
|
||||
|
||||
Questo plugin gira con i permessi del processo NSIS chiamante (tipicamente
|
||||
l'utente che esegue l'installer). Non richiede privilegi elevati per la
|
||||
compilazione né per l'esecuzione, salvo dove esplicitamente documentato.
|
||||
|
||||
DLL distribuite tramite Releases sono compilate da CI GitHub Actions con
|
||||
toolchain pinnata. Verificare hash SHA256 pubblicati nelle release.
|
||||
+679
@@ -0,0 +1,679 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Build script for NewAdvSplash plugin - All configurations
|
||||
Supports multiple build configurations with flexible parameters
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import errno
|
||||
import multiprocessing
|
||||
import os
|
||||
import shutil
|
||||
import stat
|
||||
import subprocess
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
import xml.etree.ElementTree as ET
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
from pathlib import Path
|
||||
from typing import List, Optional, Tuple
|
||||
|
||||
# Ensure stdout/stderr handle Unicode on Windows CI (cp1252 default breaks non-ASCII)
|
||||
if sys.stdout.encoding and sys.stdout.encoding.lower() not in ('utf-8', 'utf_8'):
|
||||
import io
|
||||
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
|
||||
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', errors='replace')
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Filesystem helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def _on_rmtree_error(func, path, exc_info):
|
||||
if func in (os.unlink, os.rmdir) and exc_info[1].errno == errno.EACCES:
|
||||
try:
|
||||
os.chmod(path, stat.S_IWRITE)
|
||||
func(path)
|
||||
return
|
||||
except Exception:
|
||||
pass
|
||||
for i in range(5):
|
||||
try:
|
||||
time.sleep(0.1 * (i + 1))
|
||||
if os.path.isdir(path):
|
||||
shutil.rmtree(path)
|
||||
else:
|
||||
os.unlink(path)
|
||||
return
|
||||
except Exception:
|
||||
pass
|
||||
raise exc_info[1]
|
||||
|
||||
|
||||
def robust_rmtree(path):
|
||||
if not os.path.exists(path):
|
||||
return
|
||||
try:
|
||||
shutil.rmtree(path, onexc=_on_rmtree_error)
|
||||
except TypeError:
|
||||
try:
|
||||
shutil.rmtree(path, onerror=_on_rmtree_error)
|
||||
except Exception:
|
||||
pass
|
||||
except Exception:
|
||||
try:
|
||||
shutil.rmtree(path, ignore_errors=True)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Colors & Spinner
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class Colors:
|
||||
CYAN = "\033[36m"
|
||||
GREEN = "\033[32m"
|
||||
YELLOW = "\033[33m"
|
||||
RED = "\033[31m"
|
||||
GRAY = "\033[90m"
|
||||
BLUE = "\033[34m"
|
||||
RESET = "\033[0m"
|
||||
BOLD = "\033[1m"
|
||||
BRIGHT_GREEN = "\033[92m"
|
||||
BRIGHT_CYAN = "\033[96m"
|
||||
BRIGHT_WHITE = "\033[97m"
|
||||
BRIGHT_YELLOW = "\033[93m"
|
||||
BRIGHT_RED = "\033[91m"
|
||||
|
||||
|
||||
class Spinner:
|
||||
def __init__(self, message: str = "Building...", delay: float = 0.1, total: int = 0):
|
||||
self.spinner = ['\u280b', '\u2819', '\u2839', '\u2838', '\u283c', '\u2834', '\u2826', '\u2827', '\u2807', '\u280f']
|
||||
self.delay = delay
|
||||
self.message = message
|
||||
self.running = False
|
||||
self.thread = None
|
||||
self.start_time = time.time()
|
||||
|
||||
def update(self, current=None):
|
||||
pass
|
||||
|
||||
def _spin(self):
|
||||
idx = 0
|
||||
_block = '\u28ff'
|
||||
while self.running:
|
||||
elapsed = time.time() - self.start_time
|
||||
n_blocks = int(elapsed // 2)
|
||||
time_blocks = f"{Colors.YELLOW}{_block * n_blocks}{Colors.RESET}"
|
||||
spin_char = f"{Colors.YELLOW}{self.spinner[idx % len(self.spinner)]}{Colors.RESET}"
|
||||
msg = f"{Colors.BOLD}{Colors.CYAN}{self.message}{Colors.RESET}"
|
||||
time_str = f"{Colors.GREEN}{int(elapsed)}s{Colors.RESET}"
|
||||
sys.stdout.write(f"\r{msg} {time_str} {time_blocks}{spin_char} ")
|
||||
sys.stdout.flush()
|
||||
idx += 1
|
||||
time.sleep(self.delay)
|
||||
sys.stdout.write("\r" + " " * (len(self.message) + 80) + "\r")
|
||||
sys.stdout.flush()
|
||||
|
||||
def __enter__(self):
|
||||
if sys.stdout.isatty():
|
||||
self.running = True
|
||||
self.thread = threading.Thread(target=self._spin, daemon=True)
|
||||
self.thread.start()
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
if self.running:
|
||||
self.running = False
|
||||
if self.thread:
|
||||
self.thread.join()
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Build configuration
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class BuildConfig:
|
||||
def __init__(self, name: str, config: str, platform: str, dest_dir: str):
|
||||
self.name = name
|
||||
self.config = config
|
||||
self.platform = platform
|
||||
self.dest_dir = dest_dir
|
||||
|
||||
|
||||
CONFIGS = {
|
||||
'x86-ansi': BuildConfig('x86-ansi', 'Release', 'Win32', 'x86-ansi'),
|
||||
'x86-unicode': BuildConfig('x86-unicode', 'Release Unicode', 'Win32', 'x86-unicode'),
|
||||
'x64-unicode': BuildConfig('x64-unicode', 'Release Unicode', 'x64', 'amd64-unicode'),
|
||||
}
|
||||
|
||||
DLL_NAME = 'newadvsplash.dll'
|
||||
_VSWHERE = Path(r'C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe')
|
||||
_VS_RANGES = {'2026': '[18.0,19.0)', '2022': '[17.0,18.0)'}
|
||||
_VS_TOOLSETS = {'2026': 'v145', '2022': 'v143'}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# MSBuild discovery
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def _find_msbuild_vswhere(vs_version: str) -> Optional[Tuple[Path, str, str]]:
|
||||
if not _VSWHERE.exists():
|
||||
return None
|
||||
to_try = ['2026', '2022'] if vs_version == 'auto' else [vs_version]
|
||||
for ver in to_try:
|
||||
if ver not in _VS_RANGES:
|
||||
continue
|
||||
try:
|
||||
result = subprocess.run(
|
||||
[str(_VSWHERE), '-version', _VS_RANGES[ver], '-latest',
|
||||
'-requires', 'Microsoft.Component.MSBuild',
|
||||
'-find', r'MSBuild\**\Bin\MSBuild.exe'],
|
||||
capture_output=True, text=True, timeout=15,
|
||||
)
|
||||
if result.returncode == 0:
|
||||
lines = [ln.strip() for ln in result.stdout.splitlines() if ln.strip()]
|
||||
if lines:
|
||||
p = Path(lines[0])
|
||||
if p.exists():
|
||||
return p, _VS_TOOLSETS[ver], ver
|
||||
except Exception:
|
||||
pass
|
||||
return None
|
||||
|
||||
|
||||
def find_msbuild(vs_version: str = 'auto') -> Optional[Tuple[Path, str, str]]:
|
||||
result = _find_msbuild_vswhere(vs_version)
|
||||
if result:
|
||||
return result
|
||||
# Fallback: well-known paths
|
||||
to_try = ['2026', '2022'] if vs_version == 'auto' else [vs_version]
|
||||
for ver in to_try:
|
||||
for edition in ('Community', 'Professional', 'Enterprise', 'BuildTools'):
|
||||
p = Path(rf'C:\Program Files\Microsoft Visual Studio\{ver}\{edition}\MSBuild\Current\Bin\MSBuild.exe')
|
||||
if p.exists():
|
||||
return p, _VS_TOOLSETS[ver], ver
|
||||
return None
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Project paths & version
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def get_project_paths() -> Tuple[Path, Path, Path]:
|
||||
script_dir = Path(__file__).parent.absolute()
|
||||
project_dir = script_dir / 'src'
|
||||
project_file = project_dir / 'NewAdvSplash.vcxproj'
|
||||
dist_dir = script_dir / 'dist'
|
||||
return project_dir, project_file, dist_dir
|
||||
|
||||
|
||||
def get_plugins_dir() -> Optional[Path]:
|
||||
"""Return workspace-level plugins/ dir (4 levels above src/modules/<plugin>/)."""
|
||||
p = Path(__file__).parent.parent.parent.parent / 'plugins'
|
||||
return p if p.is_dir() else None
|
||||
|
||||
|
||||
def read_version() -> str:
|
||||
vf = Path(__file__).parent / 'VERSION'
|
||||
try:
|
||||
return vf.read_text(encoding='utf-8-sig').strip()
|
||||
except Exception:
|
||||
return '0.0.0'
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# CPU info & build optimizations
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def get_cpu_info() -> dict:
|
||||
try:
|
||||
import psutil
|
||||
logical = psutil.cpu_count(logical=True)
|
||||
physical = psutil.cpu_count(logical=False)
|
||||
return {'logical_cores': logical, 'physical_cores': physical,
|
||||
'has_hyperthreading': logical > physical, 'has_psutil': True}
|
||||
except ImportError:
|
||||
n = multiprocessing.cpu_count()
|
||||
return {'logical_cores': n, 'physical_cores': n,
|
||||
'has_hyperthreading': False, 'has_psutil': False}
|
||||
|
||||
|
||||
def get_optimal_threads() -> int:
|
||||
info = get_cpu_info()
|
||||
return info['physical_cores'] if info['has_hyperthreading'] and info['physical_cores'] > 1 else info['logical_cores']
|
||||
|
||||
|
||||
def get_build_optimizations() -> List[str]:
|
||||
return [
|
||||
'/p:BuildInParallel=true',
|
||||
'/p:MultiProcessorCompilation=true',
|
||||
'/p:PreferredToolArchitecture=x64',
|
||||
'/p:UseSharedCompilation=true',
|
||||
'/nodeReuse:true',
|
||||
'/p:GenerateResourceUsePreserializedResources=true',
|
||||
]
|
||||
|
||||
|
||||
def get_memory_optimizations() -> List[str]:
|
||||
try:
|
||||
import psutil
|
||||
gb = psutil.virtual_memory().total / (1024 ** 3)
|
||||
if gb >= 16:
|
||||
return ['/p:DisableFastUpToDateCheck=false', '/p:BuildProjectReferences=true',
|
||||
'/p:UseCommonOutputDirectory=false']
|
||||
elif gb >= 8:
|
||||
return ['/p:DisableFastUpToDateCheck=false']
|
||||
return []
|
||||
except ImportError:
|
||||
return ['/p:DisableFastUpToDateCheck=false']
|
||||
|
||||
|
||||
def print_cpu_info(use_parallel: bool, use_optimizations: bool = True) -> None:
|
||||
if not use_parallel:
|
||||
print(f"{Colors.CYAN}Build mode: {Colors.RESET} {Colors.BOLD}Single-threaded{Colors.RESET}")
|
||||
if use_optimizations:
|
||||
print(f"{Colors.CYAN}Optimizations: {Colors.RESET} {Colors.GREEN}ENABLED{Colors.RESET} {Colors.GRAY}(memory, caching){Colors.RESET}")
|
||||
return
|
||||
|
||||
info = get_cpu_info()
|
||||
optimal = get_optimal_threads()
|
||||
print(f"{Colors.CYAN}Build mode: {Colors.RESET} {Colors.BRIGHT_WHITE}{'Parallel' if use_parallel else 'Sequential'}{Colors.RESET}")
|
||||
print(f"{Colors.CYAN}Logical cores: {Colors.RESET} {Colors.BRIGHT_WHITE}{info['logical_cores']}{Colors.RESET}")
|
||||
print(f"{Colors.CYAN}Physical cores: {Colors.RESET} {Colors.BRIGHT_WHITE}{info['physical_cores']}{Colors.RESET}")
|
||||
if info['has_hyperthreading']:
|
||||
print(f"{Colors.CYAN}Hyperthreading: {Colors.RESET} {Colors.BRIGHT_GREEN}ENABLED{Colors.RESET}")
|
||||
print(f"{Colors.CYAN}Optimal threads: {Colors.RESET} {Colors.BRIGHT_WHITE}{optimal}{Colors.RESET} {Colors.GRAY}(using physical cores){Colors.RESET}")
|
||||
else:
|
||||
print(f"{Colors.CYAN}Hyperthreading: {Colors.RESET} {Colors.GRAY}NOT AVAILABLE{Colors.RESET}")
|
||||
print(f"{Colors.CYAN}Optimal threads: {Colors.RESET} {Colors.BRIGHT_WHITE}{optimal}{Colors.RESET}")
|
||||
print(f"{Colors.CYAN}MSBuild threads: {Colors.RESET} {Colors.BRIGHT_WHITE}{optimal}{Colors.RESET}")
|
||||
if use_optimizations:
|
||||
print(f"{Colors.CYAN}Optimizations: {Colors.RESET} {Colors.BRIGHT_GREEN}ENABLED{Colors.RESET} {Colors.GRAY}(parallel, memory, caching){Colors.RESET}")
|
||||
try:
|
||||
import psutil
|
||||
gb = psutil.virtual_memory().total / (1024 ** 3)
|
||||
print(f"{Colors.CYAN}Available memory: {Colors.RESET} {Colors.BRIGHT_WHITE}{gb:.1f} GB{Colors.RESET}")
|
||||
except ImportError:
|
||||
print(f"{Colors.CYAN}Available memory: {Colors.RESET} {Colors.GRAY}Unknown (install psutil){Colors.RESET}")
|
||||
else:
|
||||
print(f"{Colors.CYAN}Optimizations: {Colors.RESET} {Colors.BRIGHT_RED}DISABLED{Colors.RESET}")
|
||||
if not info['has_psutil']:
|
||||
print(f"{Colors.GRAY}Note: Install 'psutil' for detailed CPU/memory info (pip install psutil){Colors.RESET}")
|
||||
print()
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Build helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def format_time(seconds: float) -> str:
|
||||
if seconds < 60:
|
||||
return f"{seconds:.2f}s"
|
||||
elif seconds < 3600:
|
||||
return f"{int(seconds // 60)}m {seconds % 60:.1f}s"
|
||||
return f"{int(seconds // 3600)}h {int((seconds % 3600) // 60)}m {seconds % 60:.0f}s"
|
||||
|
||||
|
||||
def build_configuration(
|
||||
msbuild_path: Path,
|
||||
project_file: Path,
|
||||
config: BuildConfig,
|
||||
platform_toolset: str,
|
||||
*,
|
||||
rebuild: bool = True,
|
||||
verbosity: str = 'quiet',
|
||||
parallel: bool = True,
|
||||
optimizations: bool = True,
|
||||
counter: str = "",
|
||||
capture_output: bool = False,
|
||||
) -> Tuple[bool, float, str]:
|
||||
optimal = get_optimal_threads()
|
||||
cmd = [
|
||||
str(msbuild_path),
|
||||
str(project_file),
|
||||
f'/t:{"Rebuild" if rebuild else "Build"}',
|
||||
f'/p:Configuration={config.config}',
|
||||
f'/p:Platform={config.platform}',
|
||||
f'/p:OutDir=Build\\{config.name}\\',
|
||||
f'/p:IntDir=Build\\{config.name}\\obj\\',
|
||||
'/p:WindowsTargetPlatformVersion=10.0',
|
||||
f'/p:PlatformToolset={platform_toolset}',
|
||||
f'/v:{verbosity}',
|
||||
]
|
||||
if parallel:
|
||||
cmd += [f'/maxcpucount:{optimal}', '/p:UseMultiToolTask=true', f'/p:CL_MPCount={optimal}']
|
||||
cmd += ['/p:Optimization=MaxSpeed', '/p:ExceptionHandling=Sync']
|
||||
if optimizations:
|
||||
cmd += get_build_optimizations() + get_memory_optimizations()
|
||||
|
||||
if not capture_output:
|
||||
color = Colors.BRIGHT_YELLOW
|
||||
print(f"\n{color}{'='*60}{Colors.RESET}")
|
||||
label = f"[{counter}] " if counter else ""
|
||||
print(f"{color}Building {Colors.BRIGHT_WHITE}{config.name:15s}{Colors.RESET} {color}{label}({'rebuild' if rebuild else 'incremental'}){Colors.RESET}")
|
||||
print(f"{color}{'='*60}{Colors.RESET}")
|
||||
|
||||
start = time.time()
|
||||
try:
|
||||
if capture_output:
|
||||
result = subprocess.run(cmd, check=False, capture_output=True, text=True)
|
||||
return result.returncode == 0, time.time() - start, result.stdout + result.stderr
|
||||
else:
|
||||
result = subprocess.run(cmd, check=False)
|
||||
return result.returncode == 0, time.time() - start, ""
|
||||
except Exception as e:
|
||||
elapsed = time.time() - start
|
||||
msg = f"ERROR: Build failed with exception: {e}"
|
||||
if capture_output:
|
||||
return False, elapsed, msg
|
||||
print(msg)
|
||||
return False, elapsed, ""
|
||||
|
||||
|
||||
def copy_output(project_dir: Path, dist_dir: Path, config: BuildConfig) -> Tuple[bool, int, Optional[Path]]:
|
||||
output_file = project_dir / 'Build' / config.name / DLL_NAME
|
||||
if not output_file.exists():
|
||||
print(f"ERROR: DLL not found: {output_file}")
|
||||
return False, 0, None
|
||||
dest = dist_dir / config.dest_dir
|
||||
dest.mkdir(parents=True, exist_ok=True)
|
||||
try:
|
||||
dst = dest / DLL_NAME
|
||||
shutil.copy2(output_file, dst)
|
||||
return True, output_file.stat().st_size, dst
|
||||
except Exception as e:
|
||||
print(f"ERROR: Failed to copy {config.name}: {e}")
|
||||
return False, 0, None
|
||||
|
||||
|
||||
def copy_to_plugins(dist_dir: Path, config: BuildConfig, plugins_dir: Path) -> Optional[Path]:
|
||||
"""Copy DLL from dist/<dest_dir>/ to plugins/<dest_dir>/."""
|
||||
src = dist_dir / config.dest_dir / DLL_NAME
|
||||
if not src.exists():
|
||||
return None
|
||||
dst_dir = plugins_dir / config.dest_dir
|
||||
dst_dir.mkdir(parents=True, exist_ok=True)
|
||||
dst = dst_dir / DLL_NAME
|
||||
shutil.copy2(src, dst)
|
||||
return dst
|
||||
|
||||
|
||||
def clean_build_artifacts(project_dir: Path, configs: List[BuildConfig]) -> None:
|
||||
print(f"\n{Colors.CYAN}Cleaning build artifacts...{Colors.RESET}")
|
||||
build_base = project_dir / 'Build'
|
||||
if not build_base.exists():
|
||||
return
|
||||
for cfg in configs:
|
||||
d = build_base / cfg.name
|
||||
if d.exists():
|
||||
try:
|
||||
robust_rmtree(d)
|
||||
print(f" {Colors.GRAY}- Cleaned:{Colors.RESET} {cfg.name}")
|
||||
except Exception as e:
|
||||
print(f" {Colors.RED}- Failed to clean {cfg.name}: {e}{Colors.RESET}")
|
||||
try:
|
||||
if build_base.exists() and not any(build_base.iterdir()):
|
||||
build_base.rmdir()
|
||||
except Exception:
|
||||
pass
|
||||
print(f"{Colors.BRIGHT_GREEN}Build artifacts cleaned successfully.{Colors.RESET}")
|
||||
|
||||
|
||||
def print_available_configurations(project_file: Path) -> None:
|
||||
try:
|
||||
tree = ET.parse(project_file)
|
||||
root = tree.getroot()
|
||||
ns = {'ms': 'http://schemas.microsoft.com/developer/msbuild/2003'}
|
||||
configs = []
|
||||
for ig in root.findall('.//ms:ItemGroup', ns):
|
||||
for pc in ig.findall('ms:ProjectConfiguration', ns):
|
||||
inc = pc.get('Include', '')
|
||||
parts = inc.split('|')
|
||||
if len(parts) == 2:
|
||||
configs.append(tuple(parts))
|
||||
print("Available configurations in project:")
|
||||
print("-" * 60)
|
||||
from collections import defaultdict
|
||||
grouped: dict = defaultdict(list)
|
||||
for cfg, plat in configs:
|
||||
grouped[cfg].append(plat)
|
||||
for cfg_name in sorted(grouped):
|
||||
print(f" {cfg_name:25s} - {', '.join(sorted(grouped[cfg_name]))}")
|
||||
print(f"\nTotal: {len(configs)} configuration(s)\n")
|
||||
except Exception as e:
|
||||
print(f"Could not parse project file: {e}")
|
||||
|
||||
|
||||
_print_lock = threading.Lock()
|
||||
|
||||
|
||||
def _build_configs_parallel(
|
||||
msbuild_path: Path,
|
||||
project_file: Path,
|
||||
configs: List[BuildConfig],
|
||||
platform_toolset: str,
|
||||
*,
|
||||
rebuild: bool,
|
||||
verbosity: str,
|
||||
parallel: bool,
|
||||
optimizations: bool,
|
||||
project_dir: Path,
|
||||
dist_dir: Path,
|
||||
) -> list:
|
||||
n = len(configs)
|
||||
print(f"\nParallel: launching {n} builds simultaneously...")
|
||||
print("=" * 50)
|
||||
total_start = time.time()
|
||||
results_by_idx: dict = {}
|
||||
idx_lock = threading.Lock()
|
||||
|
||||
def _build_one(idx: int, config: BuildConfig):
|
||||
import contextlib
|
||||
import io as _io
|
||||
success, build_time, captured = build_configuration(
|
||||
msbuild_path, project_file, config, platform_toolset,
|
||||
rebuild=rebuild, verbosity=verbosity,
|
||||
parallel=parallel, optimizations=optimizations,
|
||||
capture_output=True,
|
||||
)
|
||||
copy_buf = _io.StringIO()
|
||||
if success:
|
||||
with contextlib.redirect_stdout(copy_buf):
|
||||
copy_ok, file_size, dest_path = copy_output(project_dir, dist_dir, config)
|
||||
else:
|
||||
copy_ok, file_size, dest_path = False, 0, None
|
||||
|
||||
with _print_lock:
|
||||
sys.stdout.write("\r" + " " * 80 + "\r")
|
||||
sys.stdout.flush()
|
||||
tag = "OK" if (success and copy_ok) else "FAILED"
|
||||
size_str = f"{file_size:,} bytes" if file_size > 0 else "N/A"
|
||||
copy_out = copy_buf.getvalue()
|
||||
if copy_out.strip():
|
||||
print(copy_out.rstrip())
|
||||
if captured.strip():
|
||||
lines = [ln for ln in captured.splitlines() if "MSBuild" not in ln and "Copyright" not in ln]
|
||||
filtered = "\n".join(lines).strip()
|
||||
if filtered:
|
||||
print(filtered)
|
||||
color = Colors.BRIGHT_GREEN if (success and copy_ok) else Colors.RED
|
||||
print(f"{color}[{tag}]{Colors.RESET} {config.name} ({format_time(build_time)}) {size_str}")
|
||||
if dest_path:
|
||||
print(f" -> {dest_path}")
|
||||
|
||||
with idx_lock:
|
||||
results_by_idx[idx] = (config, success and copy_ok, build_time, file_size, dest_path)
|
||||
|
||||
with Spinner("Building configurations...", total=n) as s:
|
||||
with ThreadPoolExecutor(max_workers=n) as executor:
|
||||
futures = {executor.submit(_build_one, i, cfg): i for i, cfg in enumerate(configs)}
|
||||
for fut in as_completed(futures):
|
||||
s.update()
|
||||
exc = fut.exception()
|
||||
if exc:
|
||||
idx = futures[fut]
|
||||
with _print_lock:
|
||||
print(f"ERROR: worker for config index {idx} raised: {exc}")
|
||||
with idx_lock:
|
||||
results_by_idx[idx] = (configs[idx], False, 0.0, 0, None)
|
||||
|
||||
wall = time.time() - total_start
|
||||
print(f"\nAll {n} configs finished in {format_time(wall)} (wall clock)")
|
||||
return [results_by_idx[i] for i in range(n)]
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# main
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description='Build NewAdvSplash plugin for NSIS')
|
||||
parser.add_argument('--configs', nargs='+',
|
||||
choices=list(CONFIGS.keys()) + ['all'], default=None)
|
||||
parser.add_argument('--config', # singular alias used by CI
|
||||
choices=list(CONFIGS.keys()) + ['all'], default=None)
|
||||
parser.add_argument('--rebuild', action='store_true', default=True)
|
||||
parser.add_argument('--no-rebuild', action='store_false', dest='rebuild')
|
||||
parser.add_argument('--parallel', action='store_true', default=True)
|
||||
parser.add_argument('--no-parallel', action='store_false', dest='parallel')
|
||||
parser.add_argument('--verbosity',
|
||||
choices=['quiet', 'minimal', 'normal', 'detailed', 'diagnostic'],
|
||||
default='quiet')
|
||||
parser.add_argument('--clean', action='store_true', default=False)
|
||||
parser.add_argument('--list', action='store_true')
|
||||
parser.add_argument('--list-project', action='store_true')
|
||||
parser.add_argument('--no-optimizations', action='store_true')
|
||||
parser.add_argument('--vs-version', choices=['auto', '2026', '2022'], default='auto')
|
||||
parser.add_argument('--final', action='store_true', default=False,
|
||||
help='Force rebuild + clean (pre-release build)')
|
||||
parser.add_argument('--install-dir', type=Path, default=None,
|
||||
help='Copy built DLLs to this directory (in <config>/ subdirs)')
|
||||
args = parser.parse_args()
|
||||
|
||||
# Merge --config (singular) into --configs list
|
||||
if args.config and not args.configs:
|
||||
args.configs = [args.config]
|
||||
|
||||
if args.final:
|
||||
args.rebuild = True
|
||||
args.clean = True
|
||||
|
||||
project_dir, project_file, dist_dir = get_project_paths()
|
||||
|
||||
if args.list_project:
|
||||
print_available_configurations(project_file)
|
||||
return 0
|
||||
|
||||
if args.list:
|
||||
for name, config in CONFIGS.items():
|
||||
print(f" {name:15s} -> {config.config} / {config.platform}")
|
||||
return 0
|
||||
|
||||
if not project_file.exists():
|
||||
print(f"ERROR: project file not found: {project_file}", file=sys.stderr)
|
||||
return 3
|
||||
|
||||
msbuild_result = find_msbuild(args.vs_version)
|
||||
if not msbuild_result:
|
||||
print("ERROR: MSBuild not found. Install Visual Studio 2022 or 2026.", file=sys.stderr)
|
||||
return 2
|
||||
msbuild_path, platform_toolset, vs_version_name = msbuild_result
|
||||
|
||||
version = read_version()
|
||||
|
||||
if not args.configs:
|
||||
configs_to_build = list(CONFIGS.values())
|
||||
elif 'all' in args.configs:
|
||||
configs_to_build = list(CONFIGS.values())
|
||||
else:
|
||||
configs_to_build = [CONFIGS[n] for n in args.configs]
|
||||
|
||||
# Banner
|
||||
print(f"{Colors.BOLD}{Colors.BRIGHT_CYAN}{'='*60}")
|
||||
print(f"Building NewAdvSplash plugin v{version} - {Colors.BRIGHT_WHITE}{len(configs_to_build)}{Colors.RESET} {Colors.BOLD}{Colors.BRIGHT_CYAN}configuration(s)")
|
||||
print(f"{'='*60}{Colors.RESET}")
|
||||
print(f"{Colors.CYAN}VS: {Colors.RESET} {Colors.BRIGHT_WHITE}{vs_version_name}{Colors.RESET} {Colors.GRAY}({platform_toolset}){Colors.RESET}")
|
||||
print(f"{Colors.CYAN}MSBuild: {Colors.RESET} {Colors.BRIGHT_WHITE}{msbuild_path}{Colors.RESET}")
|
||||
print(f"{Colors.CYAN}Project: {Colors.RESET} {Colors.BRIGHT_WHITE}{project_file}{Colors.RESET}")
|
||||
print(f"{Colors.CYAN}Dist: {Colors.RESET} {Colors.BRIGHT_WHITE}{dist_dir}{Colors.RESET}")
|
||||
print(f"{Colors.CYAN}Rebuild: {Colors.RESET} {Colors.BRIGHT_WHITE}{args.rebuild}{Colors.RESET}")
|
||||
print(f"{Colors.CYAN}Verbosity: {Colors.RESET} {Colors.BRIGHT_WHITE}{args.verbosity}{Colors.RESET}")
|
||||
print()
|
||||
|
||||
use_optimizations = not args.no_optimizations
|
||||
print_cpu_info(args.parallel, use_optimizations)
|
||||
|
||||
build_results = []
|
||||
total_start = time.time()
|
||||
|
||||
if args.parallel and len(configs_to_build) > 1:
|
||||
build_results = _build_configs_parallel(
|
||||
msbuild_path, project_file, configs_to_build, platform_toolset,
|
||||
rebuild=args.rebuild, verbosity=args.verbosity,
|
||||
parallel=True, optimizations=use_optimizations,
|
||||
project_dir=project_dir, dist_dir=dist_dir,
|
||||
)
|
||||
else:
|
||||
for i, config in enumerate(configs_to_build, 1):
|
||||
success, b_time, _ = build_configuration(
|
||||
msbuild_path, project_file, config, platform_toolset,
|
||||
rebuild=args.rebuild, verbosity=args.verbosity,
|
||||
parallel=args.parallel, optimizations=use_optimizations,
|
||||
counter=f"{i}/{len(configs_to_build)}",
|
||||
)
|
||||
if success:
|
||||
ok, size, path = copy_output(project_dir, dist_dir, config)
|
||||
build_results.append((config, ok, b_time, size, path))
|
||||
else:
|
||||
build_results.append((config, False, b_time, 0, None))
|
||||
|
||||
total_time = time.time() - total_start
|
||||
all_success = all(res[1] for res in build_results)
|
||||
|
||||
print(f"\n{Colors.BOLD}{Colors.BRIGHT_GREEN if all_success else Colors.RED}{'='*50}")
|
||||
print("ALL BUILDS SUCCESSFUL!" if all_success else "SOME BUILDS FAILED!")
|
||||
print(f"{'='*50}{Colors.RESET}")
|
||||
|
||||
# Copy to workspace plugins/ dir if present
|
||||
plugins_dir = get_plugins_dir()
|
||||
plugins_copied = []
|
||||
if plugins_dir and all_success:
|
||||
for cfg, ok, _, _, _ in build_results:
|
||||
if ok:
|
||||
dst = copy_to_plugins(dist_dir, cfg, plugins_dir)
|
||||
if dst:
|
||||
plugins_copied.append(str(dst))
|
||||
if plugins_copied:
|
||||
print(f"\n{Colors.CYAN}Installed to plugins/:{Colors.RESET}")
|
||||
for p in plugins_copied:
|
||||
print(f" {Colors.GRAY}->{Colors.RESET} {p}")
|
||||
|
||||
if args.install_dir and all_success:
|
||||
print(f"\n{Colors.CYAN}Installing to {args.install_dir}...{Colors.RESET}")
|
||||
for cfg, ok, _, _, path in build_results:
|
||||
if ok and path:
|
||||
dest = args.install_dir / cfg.dest_dir
|
||||
dest.mkdir(parents=True, exist_ok=True)
|
||||
shutil.copy2(path, dest / DLL_NAME)
|
||||
print(f" {Colors.GRAY}- Installed:{Colors.RESET} {dest / DLL_NAME}")
|
||||
|
||||
print(f"\n{Colors.BOLD}{Colors.BRIGHT_CYAN}{'-'*50}")
|
||||
print(f"Build Summary - VS {vs_version_name} ({platform_toolset}):")
|
||||
for cfg, ok, b_time, size, _ in build_results:
|
||||
color = Colors.GREEN if ok else Colors.RED
|
||||
tag = "OK " if ok else "FAIL"
|
||||
print(f" {color}{tag}{Colors.RESET} {cfg.name:15s} - {format_time(b_time):8s} - {size:11,d} bytes")
|
||||
print(f"{Colors.BOLD}{Colors.BRIGHT_CYAN}{'-'*50}{Colors.RESET}")
|
||||
print(f"Total time: {format_time(total_time)}\n")
|
||||
|
||||
if args.clean:
|
||||
clean_build_artifacts(project_dir, configs_to_build)
|
||||
|
||||
return 0 if all_success else 1
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
@@ -0,0 +1,177 @@
|
||||
# Microsoft Developer Studio Project File - Name="advsplash" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=advsplash - Win32 Release
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "advsplash.mak".
|
||||
!MESSAGE
|
||||
!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 "advsplash.mak" CFG="advsplash - Win32 Release"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "advsplash - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "advsplash - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "advsplash - Win32 Release_Unicode" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "advsplash - Win32 Debug_Unicode" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "advsplash - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /Og /Os /Oy /I "..\ExDll" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FD /c
|
||||
# SUBTRACT CPP /Ox /Ow /YX
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
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 winmm.lib /nologo /subsystem:windows /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib vfw32.lib winmm.lib ole32.lib oleaut32.lib uuid.lib msvcrt.lib /nologo /entry:"DllMain" /subsystem:windows /dll /machine:I386 /nodefaultlib /out:"../../Plugins/newadvsplash.dll" /opt:nowin98
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "advsplash - 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 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\ExDll" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /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 /subsystem:windows /debug /machine:I386 /pdbtype:sept
|
||||
# ADD 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 vfw32.lib winmm.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"../../Plugins/newadvsplash.dll" /pdbtype:sept
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "advsplash - Win32 Release_Unicode"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release_Unicode"
|
||||
# PROP BASE Intermediate_Dir "Release_Unicode"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release_Unicode"
|
||||
# PROP Intermediate_Dir "Release_Unicode"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_UNICODE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /Og /Os /Oy /I "..\ExDll" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /D "_MBCS" /D "_USRDLL" /FD /c
|
||||
# SUBTRACT CPP /Ox /Ow /YX
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
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 winmm.lib /nologo /subsystem:windows /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib vfw32.lib winmm.lib ole32.lib oleaut32.lib uuid.lib msvcrt.lib /nologo /entry:"DllMain" /subsystem:windows /dll /machine:I386 /nodefaultlib /out:"../../Unicode/plugins/newadvsplash.dll" /opt:nowin98
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "advsplash - Win32 Debug_Unicode"
|
||||
|
||||
# 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 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_UNICODE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\ExDll" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /D "_MBCS" /D "_USRDLL" /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 /subsystem:windows /debug /machine:I386 /pdbtype:sept
|
||||
# ADD 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 vfw32.lib winmm.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"../../Unicode/plugins/newadvsplash.dll" /pdbtype:sept
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "advsplash - Win32 Release"
|
||||
# Name "advsplash - Win32 Debug"
|
||||
# Name "advsplash - Win32 Release_Unicode"
|
||||
# Name "advsplash - Win32 Debug_Unicode"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\advsplash.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\gif.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\ExDLL\exdll.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -0,0 +1,28 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "advsplash"=.\advsplash.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
@@ -0,0 +1,69 @@
|
||||
NewAdvSplash.dll - plug-in that lets you throw
|
||||
up a splash screen in NSIS installers with
|
||||
fading effects (win2k/xp) and transparency.
|
||||
At the same time can play wav-mp3 sound file.
|
||||
|
||||
Usage:
|
||||
|
||||
1) newadvsplash::show [/NOUNLOAD] Delay FadeIn FadeOut KeyColor [/BANNER] [/PASSIVE] [/NOCANCEL] FileName
|
||||
|
||||
Delay - time (milliseconds) to show image
|
||||
FadeIn - time to show the fadein scene
|
||||
FadeOut - time to show the fadeout scene
|
||||
KeyColor - color used for transparency, could be any RGB value
|
||||
(for ex. R=255 G=100 B=16 -> KeyColor=0xFF6410),
|
||||
use KeyColor=-1 if there is no transparent color at your image.
|
||||
If KeyColor=-2 and image type is gif, plug-in attempts to extract
|
||||
transparency color value from the file header. For gif images
|
||||
transparency on the static background works even if KeyColor=-1.
|
||||
/BANNER - returns control to installer immediatelly after plug-in
|
||||
activation. Not depends on installer page - parent window NULL.
|
||||
/NOCANCEL - disables 'exit on user click' default behaviour.
|
||||
/PASSIVE - not forces splash window to foreground.
|
||||
FileName - splash image filename (with extension!). Bmp, gif and jpg
|
||||
image types are supported.
|
||||
|
||||
For example:
|
||||
|
||||
newadvsplash::show 3000 0 0 -2 "$PLUGINSDIR\catch.gif"
|
||||
or
|
||||
newadvsplash::show /NOUNLOAD 1000 600 400 0xFF6410 /BANNER "$TEMP\spltmp.bmp"
|
||||
|
||||
Use /NOUNLOAD with /BANNER key - this case plug-in not waits for
|
||||
the end of 'show' and returns control to installer. If used in .onInit
|
||||
function, /BANNER key requires 'ShowWindow $HWNDPARENT 2' in .onGUIInit
|
||||
|
||||
|
||||
2) newadvsplash::stop [/WAIT | /FADEOUT]
|
||||
|
||||
Without options terminates banner.
|
||||
With /WAIT option waits for the end.
|
||||
With /FADEOUT option forces banner close with fade out effect ('Delay' -> 0).
|
||||
|
||||
|
||||
3) newadvsplash::play /NOUNLOAD [/LOOP] FileName
|
||||
|
||||
FileName - sound filename to play (with extension, wav, mp3 ...).
|
||||
Empty Filename string "" stops sound.
|
||||
For example:
|
||||
|
||||
newadvsplash::play /NOUNLOAD /LOOP "$PLUGINSDIR\snd.mp3"
|
||||
newadvsplash::show 2000 1000 500 -1 "$PLUGINSDIR\iamfat.jpg"
|
||||
|
||||
|
||||
4) newadvsplash::hwnd /NOUNLOAD
|
||||
|
||||
Gets splash window handle.
|
||||
For example:
|
||||
|
||||
newadvsplash::hwnd /NOUNLOAD
|
||||
Pop $0 ; $0 is window handle now
|
||||
|
||||
Compatibility:
|
||||
Basic - Win95 and later.
|
||||
Fadein/fadeout - win2k/winxp.
|
||||
|
||||
Original code - Justin
|
||||
Converted to a plugin DLL by Amir Szekely (kichik)
|
||||
Fading and transparency by Nik Medved (brainsucker)
|
||||
Gif and jpeg support, /BANNER and /CANCEL, mp3 support - Takhir Bedertdinov
|
||||
@@ -0,0 +1,82 @@
|
||||
{{PageAuthor|Takhir}}
|
||||
|
||||
== Links ==
|
||||
Download:<br>
|
||||
<attach>NewAdvSplash.zip</attach><br>
|
||||
[http://forums.winamp.com/showthread.php?s=&threadid=197479 Forum thread]
|
||||
|
||||
== Description ==
|
||||
|
||||
NewAdvSplash.dll - startup image banner plug-in with fading effects (win2k/xp) and transparency. At the same time can play sound file. On the base of AdvSplash NSIS plug-in with following add-ons: allows background installer initialization (async-banner mode); plays mp3 files; gif, jpeg and some other OleLoadPicture() formats; "passive" mode - not forces spalsh window to foreground; can return splash HWND to work with other plug-ins (Marquee, AnimGif) in the async mode.
|
||||
Compatibility: basic - Win95 and later, fadein/fadeout - win2k/winxp.
|
||||
|
||||
== Installing ==
|
||||
|
||||
Unzip and place the .dll file into the Plugins directory.
|
||||
|
||||
== Entry points and parameters (NSIS script) ==
|
||||
|
||||
newadvsplash::show [/NOUNLOAD] Delay FadeIn FadeOut KeyColor [/BANNER] [/PASSIVE] [/NOCANCEL] FileName
|
||||
|
||||
; Delay
|
||||
: time (milliseconds) to show image
|
||||
|
||||
; FadeIn
|
||||
: time to show the fadein scene
|
||||
|
||||
; FadeOut
|
||||
: time to show the fadeout scene
|
||||
|
||||
; KeyColor
|
||||
: color used for transparency, could be any RGB value (for ex. R=255 G=100 B=16 -> KeyColor=0xFF6410), use KeyColor=-1 if there is no transparent color at your image. If KeyColor=-2 and image type is gif, plug-in attempts to extract transparency color value from the file header. For gif images transparency on the static background works even if KeyColor=-1.
|
||||
|
||||
; /BANNER
|
||||
: returns control to installer immediatelly after plug-in activation.
|
||||
|
||||
; /NOCANCEL
|
||||
: disables 'exit on user click' default behaviour.
|
||||
|
||||
; /PASSIVE
|
||||
: not forces spalsh window to foreground
|
||||
|
||||
; FileName
|
||||
: splash image filename (with extension!). Bmp, gif and jpg image types supported.
|
||||
|
||||
|
||||
newadvsplash::stop [/WAIT | /FADEOUT]
|
||||
|
||||
: For /BANNER mode only! Without options terminates banner.
|
||||
: With /WAIT option waits for the end.
|
||||
: With /FADEOUT option forces banner close with fade out effect ('Delay' -> 0).
|
||||
|
||||
|
||||
newadvsplash::play /NOUNLOAD [/LOOP] FileName
|
||||
|
||||
; FileName
|
||||
: sound filename to play (with extension, wav, mp3 ...). Empty Filename string "" stops playing ('show' end does this as well).
|
||||
|
||||
; /LOOP
|
||||
: loops sound.
|
||||
|
||||
|
||||
newadvsplash::hwnd
|
||||
|
||||
: Gets splash window handle (use Pop to take it from stack)
|
||||
|
||||
== Examples ==
|
||||
'Modeless' logo with sound
|
||||
<highlight-nsis>
|
||||
newadvsplash::play /NOUNLOAD /LOOP "$PLUGINSDIR\snd.mp3"
|
||||
newadvsplash::show /NOUNLOAD 2000 1000 500 -2 /BANNER "$PLUGINSDIR\logo.gif"
|
||||
; add your initialization code here
|
||||
newadvsplash::stop /WAIT
|
||||
</highlight-nsis>
|
||||
|
||||
Simple logo
|
||||
<highlight-nsis>
|
||||
newadvsplash::show 2000 1000 500 -1 "$PLUGINSDIR\logo.jpg"
|
||||
</highlight-nsis>
|
||||
|
||||
No return value.
|
||||
|
||||
[[Category:Plugins]]
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 8.3 KiB |
@@ -0,0 +1,51 @@
|
||||
;-----------------------------
|
||||
; Requires AnimGif plug-in
|
||||
|
||||
Name "NewAdvSplash AnimBanner test"
|
||||
OutFile "animbanner.exe"
|
||||
|
||||
!define IMG_NAME aist.gif
|
||||
|
||||
!include "MUI.nsh"
|
||||
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE anb
|
||||
!insertmacro MUI_PAGE_WELCOME
|
||||
!insertmacro MUI_PAGE_INSTFILES
|
||||
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE bna
|
||||
!insertmacro MUI_PAGE_FINISH
|
||||
!insertmacro MUI_LANGUAGE "English"
|
||||
|
||||
|
||||
Function anb
|
||||
|
||||
SetOutPath "$PLUGINSDIR"
|
||||
File ${IMG_NAME}
|
||||
|
||||
newadvsplash::show /NOUNLOAD 2000 1000 500 -1 /BANNER "$PLUGINSDIR\${IMG_NAME}"
|
||||
newadvsplash::hwnd /NOUNLOAD
|
||||
Pop $0
|
||||
AnimGif::play /NOUNLOAD /hwnd=$0 /bgcol=0xffffff "$PLUGINSDIR\${IMG_NAME}"
|
||||
|
||||
FunctionEnd
|
||||
|
||||
Function bna
|
||||
|
||||
newadvsplash::stop
|
||||
AnimGif::stop
|
||||
|
||||
Delete "$PLUGINSDIR\${IMG_NAME}"
|
||||
SetOutPath "$EXEDIR"
|
||||
|
||||
FunctionEnd
|
||||
|
||||
Section
|
||||
|
||||
newadvsplash::stop /wait
|
||||
AnimGif::stop
|
||||
Sleep 1000
|
||||
newadvsplash::show /NOUNLOAD 2000 1000 500 -1 /BANNER "$PLUGINSDIR\${IMG_NAME}"
|
||||
newadvsplash::hwnd /NOUNLOAD
|
||||
Pop $0
|
||||
AnimGif::play /NOUNLOAD /hwnd=$0 /bgcol=0xffffff "$PLUGINSDIR\${IMG_NAME}"
|
||||
Sleep 1000
|
||||
|
||||
SectionEnd
|
||||
@@ -0,0 +1,55 @@
|
||||
;-----------------------------
|
||||
; Requires AnimGif plug-in
|
||||
|
||||
Name "NewAdvSplash AnimSplash test"
|
||||
OutFile "animsplash.exe"
|
||||
|
||||
!define IMG_NAME aist.gif
|
||||
|
||||
!include "MUI.nsh"
|
||||
!define MUI_CUSTOMFUNCTION_GUIINIT begin
|
||||
!insertmacro MUI_PAGE_WELCOME
|
||||
!insertmacro MUI_LANGUAGE "English"
|
||||
|
||||
|
||||
Function .onInit
|
||||
|
||||
; following 2 lines can minimize all other desktop windows
|
||||
; FindWindow $0 "Shell_TrayWnd"
|
||||
; SendMessage $0 ${WM_COMMAND} 415 0
|
||||
|
||||
; the plugins dir is automatically deleted when the installer exits
|
||||
InitPluginsDir
|
||||
SetOutPath "$PLUGINSDIR"
|
||||
|
||||
|
||||
; Modeless banner sample: show + wait
|
||||
File "aist.gif"
|
||||
newadvsplash::show /NOUNLOAD 2000 1000 500 -1 /BANNER "$PLUGINSDIR\${IMG_NAME}"
|
||||
newadvsplash::hwnd /NOUNLOAD
|
||||
Pop $0
|
||||
AnimGif::play /NOUNLOAD /hwnd=$0 /bgcol=0xffffff "$PLUGINSDIR\${IMG_NAME}"
|
||||
|
||||
; you can add some background initialization code here (3.5 sec - aist.gif play time)
|
||||
; wait & stop code also may be placed here, I moved them to .onGUIInit
|
||||
; as a /BANNER (modeless) sample only.
|
||||
|
||||
FunctionEnd
|
||||
|
||||
|
||||
Function begin
|
||||
|
||||
newadvsplash::stop /wait ; waits or exits immediately if 'show' already finished
|
||||
AnimGif::stop
|
||||
|
||||
Delete "$PLUGINSDIR\${IMG_NAME}"
|
||||
SetOutPath "$EXEDIR"
|
||||
|
||||
; plug-in requires this to be called in .onGUIInit in the BANNER mode only
|
||||
ShowWindow $HWNDPARENT ${SW_RESTORE}
|
||||
|
||||
FunctionEnd
|
||||
|
||||
|
||||
Section
|
||||
SectionEnd
|
||||
@@ -0,0 +1,43 @@
|
||||
|
||||
Name "NewAdvSplash BannerMUI test"
|
||||
OutFile "bannermui.exe"
|
||||
|
||||
|
||||
!include "MUI.nsh"
|
||||
!define MUI_CUSTOMFUNCTION_GUIINIT MUIGUIInit
|
||||
!insertmacro MUI_PAGE_WELCOME
|
||||
!insertmacro MUI_LANGUAGE "English"
|
||||
|
||||
!define IMG_NAME aist.gif
|
||||
|
||||
Function .onInit
|
||||
|
||||
; the plugins dir is automatically deleted when the installer exits
|
||||
InitPluginsDir
|
||||
SetOutPath "$PLUGINSDIR"
|
||||
|
||||
; Modeless banner sample: show + wait
|
||||
File ${IMG_NAME}
|
||||
newadvsplash::show /NOUNLOAD 2000 1000 500 -2 /BANNER "$PLUGINSDIR\${IMG_NAME}"
|
||||
Sleep 2000 ; not changes 3.5 sec of 'show time'. add your code instead of sleep
|
||||
|
||||
FunctionEnd
|
||||
|
||||
|
||||
; MUI requires custom function definition
|
||||
Function MUIGUIInit
|
||||
|
||||
newadvsplash::stop /wait ; waits or exits immediately if finished, use just 'stop' to terminate
|
||||
|
||||
Delete "$PLUGINSDIR\${IMG_NAME}"
|
||||
SetOutPath "$EXEDIR"
|
||||
|
||||
; plug-in requires this to be called in .onGUIInit
|
||||
; if you use 'show' in the .onInit function with /BANNER key.
|
||||
ShowWindow $HWNDPARENT ${SW_RESTORE}
|
||||
|
||||
FunctionEnd
|
||||
|
||||
|
||||
Section
|
||||
SectionEnd
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
@@ -0,0 +1,51 @@
|
||||
|
||||
Name "NewAdvSplash.dll test"
|
||||
OutFile "newadvsplash.exe"
|
||||
|
||||
!define IMG_NAME1 splash.bmp
|
||||
!define IMG_NAME2 aist.gif
|
||||
|
||||
!include WinMessages.nsh
|
||||
|
||||
|
||||
Function .onInit
|
||||
|
||||
; the plugins dir is automatically deleted when the installer exits
|
||||
InitPluginsDir
|
||||
SetOutPath "$PLUGINSDIR"
|
||||
|
||||
; optional - mp3, use /LOOP key for 'non-stop'
|
||||
# File "09.mp3"
|
||||
# newadvsplash::play /NOUNLOAD "$PLUGINSDIR\09.mp3"
|
||||
|
||||
; Modal banner sample: show
|
||||
File "/oname=$PLUGINSDIR\${IMG_NAME1}" "${NSISDIR}\Contrib\Graphics\Wizard\llama.bmp"
|
||||
newadvsplash::show 1000 100 500 0x04025C /NOCANCEL "$PLUGINSDIR\${IMG_NAME1}"
|
||||
Delete "$PLUGINSDIR\${IMG_NAME1}"
|
||||
Sleep 500 ; optional
|
||||
|
||||
; Modeless banner sample: show + wait
|
||||
File ${IMG_NAME2}
|
||||
newadvsplash::show /NOUNLOAD 2000 1000 500 -2 /BANNER "$PLUGINSDIR\${IMG_NAME2}"
|
||||
Sleep 2000 ; not changes 3.5 sec of 'show time'. add your code instead of sleep
|
||||
|
||||
FunctionEnd
|
||||
|
||||
|
||||
; MUI requires custom function definition
|
||||
Function .onGUIInit
|
||||
|
||||
newadvsplash::stop /wait ; waits or exits immediately if finished, remove /wait to terminate now
|
||||
|
||||
Delete "$PLUGINSDIR\${IMG_NAME2}"
|
||||
SetOutPath "$EXEDIR"
|
||||
|
||||
; plug-in requires this to be called in .onGUIInit
|
||||
; if you use 'show' in the .onInit function with /BANNER key.
|
||||
ShowWindow $HWNDPARENT ${SW_RESTORE}
|
||||
|
||||
FunctionEnd
|
||||
|
||||
|
||||
Section
|
||||
SectionEnd
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
Name "NewAdvSplash.dll StopFade test"
|
||||
OutFile "stopfade.exe"
|
||||
|
||||
!define IMG_NAME2 aist.gif
|
||||
|
||||
!include WinMessages.nsh
|
||||
|
||||
|
||||
; MUI requires custom function definition
|
||||
Function .onGUIInit
|
||||
|
||||
InitPluginsDir
|
||||
SetOutPath "$PLUGINSDIR"
|
||||
|
||||
|
||||
; Modeless banner with variable initialization time - up to 10 sec
|
||||
; uses 'soft' stop() with fade out
|
||||
|
||||
File ${IMG_NAME2}
|
||||
newadvsplash::show /NOUNLOAD 10000 1000 500 -2 /BANNER "$PLUGINSDIR\${IMG_NAME2}"
|
||||
Sleep 2000 ; add here your initialization code (up to 11 sec) instead of sleep
|
||||
newadvsplash::stop /fadeout
|
||||
# newadvsplash::stop /wait
|
||||
# newadvsplash::stop
|
||||
Delete "$PLUGINSDIR\${IMG_NAME2}"
|
||||
SetOutPath "$EXEDIR"
|
||||
|
||||
FunctionEnd
|
||||
|
||||
|
||||
|
||||
Section
|
||||
SectionEnd
|
||||
@@ -0,0 +1,38 @@
|
||||
|
||||
; Requires marquee plug-in
|
||||
; Displays text on the splash window
|
||||
|
||||
!define IMG_NAME catch.ver.gif
|
||||
|
||||
Name "NewAdvSplash Version test"
|
||||
OutFile "version.exe"
|
||||
|
||||
!include WinMessages.nsh
|
||||
|
||||
Function .onInit
|
||||
|
||||
InitPluginsDir
|
||||
SetOutPath "$PLUGINSDIR"
|
||||
|
||||
File "${IMG_NAME}"
|
||||
newadvsplash::show /NOUNLOAD 3000 1000 500 -2 /BANNER /NOCANCEL "$PLUGINSDIR\${IMG_NAME}"
|
||||
newadvsplash::hwnd /NOUNLOAD
|
||||
Pop $0
|
||||
Sleep 100 ; to make window visible - this case you can skip /GCOL=00ff00 parameter
|
||||
marquee::start /NOUNLOAD /left=73 /right=2 /COLOR=ff0000 /hwnd=$0 /step=0 /interval=100 /top=15 /height=35 /width=17 /start=right "v. 3.17"
|
||||
|
||||
FunctionEnd
|
||||
|
||||
Function .onGUIInit
|
||||
|
||||
newadvsplash::stop /wait
|
||||
marquee::stop
|
||||
Delete "$PLUGINSDIR\${IMG_NAME}"
|
||||
SetOutPath "$EXEDIR" ; after this system can remove PLUGINSDIR
|
||||
ShowWindow $HWNDPARENT ${SW_RESTORE}
|
||||
|
||||
FunctionEnd
|
||||
|
||||
|
||||
Section
|
||||
SectionEnd
|
||||
@@ -0,0 +1,186 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release Unicode|Win32">
|
||||
<Configuration>Release Unicode</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release Unicode|x64">
|
||||
<Configuration>Release Unicode</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>17.0</VCProjectVersion>
|
||||
<ProjectGuid>{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>NewAdvSplash</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'"
|
||||
Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'"
|
||||
Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
|
||||
Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')"
|
||||
Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets"
|
||||
Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
|
||||
Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')"
|
||||
Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
|
||||
Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')"
|
||||
Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets"
|
||||
Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
|
||||
Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')"
|
||||
Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<PreprocessorDefinitions>
|
||||
WIN32;NDEBUG;_WINDOWS;_USRDLL;EXDLL_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<AdditionalDependencies>
|
||||
kernel32.lib;user32.lib;gdi32.lib;ole32.lib;vfw32.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ModuleDefinitionFile>
|
||||
</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<PreprocessorDefinitions>
|
||||
WIN32;NDEBUG;_WINDOWS;_USRDLL;EXDLL_EXPORTS;UNICODE;_UNICODE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<AdditionalDependencies>
|
||||
kernel32.lib;user32.lib;gdi32.lib;ole32.lib;vfw32.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ModuleDefinitionFile>
|
||||
</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<PreprocessorDefinitions>
|
||||
NDEBUG;_WINDOWS;_USRDLL;EXDLL_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<AdditionalDependencies>
|
||||
kernel32.lib;user32.lib;gdi32.lib;ole32.lib;vfw32.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ModuleDefinitionFile>
|
||||
</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<PreprocessorDefinitions>
|
||||
NDEBUG;_WINDOWS;_USRDLL;EXDLL_EXPORTS;UNICODE;_UNICODE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<AdditionalDependencies>
|
||||
kernel32.lib;user32.lib;gdi32.lib;ole32.lib;vfw32.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ModuleDefinitionFile>
|
||||
</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="advsplash.cpp" />
|
||||
<ClCompile Include="gif.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,539 @@
|
||||
/***************************************************
|
||||
* FILE NAME: advsplash.cpp
|
||||
*
|
||||
* Copyright 2003 - Present NSIS
|
||||
*
|
||||
* PURPOSE:
|
||||
* Splash screen in NSIS installers with fading
|
||||
* and transparency effects
|
||||
*
|
||||
* CHANGE HISTORY
|
||||
*
|
||||
* Author Date Modifications
|
||||
*
|
||||
* Justin Original
|
||||
* Amir Szekely (kichik) Converted to a plugin DLL
|
||||
* Nik Medved (brainsucker) Fading and transparency by
|
||||
* Takhir Bedertdinov
|
||||
* 10-26-2004 Gif and jpeg support
|
||||
* 06-25-2005 modeless mode
|
||||
* 08-30-2005 hwnd entry point for AnimGif
|
||||
* 10-16-2005 "no transparency" bug for white bg images fixed
|
||||
* 03-04-2006 /PASSIVE mode
|
||||
* 04-04-2006 NULL parent HWND for /BANNER mode
|
||||
* hbatista
|
||||
* 04-05-2007 Unregister window on 'stop'
|
||||
* Takhir
|
||||
* 11-20-2007 "stop /fadeout" option - decreases sleep time
|
||||
* "stop /wait" fully replaces ::wait call
|
||||
**************************************************/
|
||||
|
||||
// For layered windows
|
||||
#define _WIN32_WINNT 0x0500
|
||||
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
#include <windowsx.h>
|
||||
#include <olectl.h>
|
||||
#include <stdio.h>
|
||||
#include <vfw.h>
|
||||
#include "exdll.h"
|
||||
|
||||
#ifndef WS_EX_LAYERED
|
||||
#define WS_EX_LAYERED 0x00080000
|
||||
#define LWA_COLORKEY 0x00000001
|
||||
#define LWA_ALPHA 0x00000002
|
||||
#endif // ndef WS_EX_LAYERED
|
||||
|
||||
#define RESOLUTION 32 // 32 ms ~ 30 fps ;) (32? I like SHR more than iDIV ;)
|
||||
#define MAX_SHOW_TIME 60000
|
||||
|
||||
enum FADE_STATES
|
||||
{
|
||||
FADE_IN,
|
||||
FADE_SLEEP,
|
||||
FADE_OUT
|
||||
};
|
||||
|
||||
const TCHAR classname[4] = _T("_sp");
|
||||
HWND myWnd = NULL;
|
||||
HINSTANCE g_hInstance;
|
||||
HANDLE hThread = NULL;
|
||||
BITMAP bm;
|
||||
HBITMAP g_hbm;
|
||||
int resolution = RESOLUTION;
|
||||
int sleep_val, fadein_val, fadeout_val, state, timeleft, keycolor, alphaparam;
|
||||
LPPICTURE pIPicture = NULL;
|
||||
bool modal = true, nocancel = false, setfg = true;
|
||||
UINT timerEvent;
|
||||
static WNDCLASS wc;
|
||||
|
||||
typedef BOOL(_stdcall *_tSetLayeredWindowAttributesProc)(HWND hwnd, // handle to the layered window
|
||||
COLORREF crKey, // specifies the color key
|
||||
BYTE bAlpha, // value for the blend function
|
||||
DWORD dwFlags // action
|
||||
);
|
||||
_tSetLayeredWindowAttributesProc SetLayeredWindowAttributesProc;
|
||||
|
||||
int getTransparencyColor(TCHAR *fn_src);
|
||||
|
||||
void sf(HWND hw)
|
||||
{
|
||||
DWORD ctid = GetCurrentThreadId();
|
||||
DWORD ftid = GetWindowThreadProcessId(GetForegroundWindow(), NULL);
|
||||
AttachThreadInput(ftid, ctid, TRUE);
|
||||
SetForegroundWindow(hw);
|
||||
AttachThreadInput(ftid, ctid, FALSE);
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
* FUNCTION NAME: WndProc()
|
||||
* PURPOSE:
|
||||
* window proc.
|
||||
* SPECIAL CONSIDERATIONS:
|
||||
* for paint purposes mainly
|
||||
*****************************************************/
|
||||
static LRESULT CALLBACK WndProc(HWND hwnd,
|
||||
UINT uMsg,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam)
|
||||
{
|
||||
PAINTSTRUCT ps;
|
||||
RECT r;
|
||||
long w, h;
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_CREATE:
|
||||
SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
|
||||
SetWindowLong(hwnd, GWL_STYLE, 0);
|
||||
SetWindowPos(hwnd, NULL,
|
||||
r.left + (r.right - r.left - bm.bmWidth) / 2,
|
||||
r.top + (r.bottom - r.top - bm.bmHeight) / 2,
|
||||
bm.bmWidth, bm.bmHeight,
|
||||
SWP_NOZORDER | SWP_SHOWWINDOW);
|
||||
return 0;
|
||||
|
||||
case WM_PAINT:
|
||||
BeginPaint(hwnd, &ps);
|
||||
if (pIPicture != NULL)
|
||||
{
|
||||
GetClientRect(hwnd, &r);
|
||||
pIPicture->get_Width(&w);
|
||||
pIPicture->get_Height(&h);
|
||||
pIPicture->Render(ps.hdc, r.left,
|
||||
r.top, r.right - r.left, r.bottom - r.top, 0, h, w, -h, &r);
|
||||
}
|
||||
EndPaint(hwnd, &ps);
|
||||
|
||||
case WM_CLOSE:
|
||||
return 0;
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
if (nocancel)
|
||||
break;
|
||||
case WM_TIMER:
|
||||
timeKillEvent(timerEvent);
|
||||
if (setfg)
|
||||
sf(hwnd);
|
||||
PlaySound(0, 0, 0);
|
||||
DestroyWindow(hwnd);
|
||||
break;
|
||||
}
|
||||
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
* FUNCTION NAME: SetTransparentRegion()
|
||||
* PURPOSE:
|
||||
* creates window region
|
||||
* SPECIAL CONSIDERATIONS:
|
||||
* kind of skin creation from bmp
|
||||
*****************************************************/
|
||||
void SetTransparentRegion(HWND myWnd)
|
||||
{
|
||||
HDC dc;
|
||||
int x, y;
|
||||
HRGN region, cutrgn;
|
||||
BITMAPINFO bmi = {{sizeof(BITMAPINFOHEADER), bm.bmWidth, bm.bmHeight, 1, 32, BI_RGB, 0, 0, 0, 0, 0}};
|
||||
int size = bm.bmWidth * bm.bmHeight * 4;
|
||||
int *pbmp = (int *)GlobalAlloc(GPTR, size),
|
||||
*bmp;
|
||||
|
||||
bmp = pbmp;
|
||||
dc = CreateCompatibleDC(NULL);
|
||||
SelectObject(dc, g_hbm);
|
||||
|
||||
x = GetDIBits(dc, g_hbm, 0, bm.bmHeight, bmp, &bmi, DIB_RGB_COLORS);
|
||||
region = CreateRectRgn(0, 0, bm.bmWidth, bm.bmHeight);
|
||||
|
||||
// Search for transparent pixels
|
||||
for (y = bm.bmHeight - 1; y >= 0; y--)
|
||||
for (x = 0; x < bm.bmWidth;)
|
||||
if ((*bmp & 0xFFFFFF) == keycolor)
|
||||
{
|
||||
int j = x;
|
||||
while ((x < bm.bmWidth) && ((*bmp & 0xFFFFFF) == keycolor))
|
||||
bmp++, x++;
|
||||
|
||||
// Cut transparent pixels from the original region
|
||||
cutrgn = CreateRectRgn(j, y, x, y + 1);
|
||||
CombineRgn(region, region, cutrgn, RGN_XOR);
|
||||
DeleteObject(cutrgn);
|
||||
}
|
||||
else
|
||||
bmp++, x++;
|
||||
|
||||
// Set resulting region.
|
||||
SetWindowRgn(myWnd, region, TRUE);
|
||||
DeleteObject(region);
|
||||
DeleteObject(dc);
|
||||
GlobalFree(pbmp);
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
* FUNCTION NAME: TimeProc()
|
||||
* PURPOSE:
|
||||
* fade in/out tracking
|
||||
* SPECIAL CONSIDERATIONS:
|
||||
* works without WM_TIMER
|
||||
*****************************************************/
|
||||
void CALLBACK TimeProc(UINT uID,
|
||||
UINT uMsg,
|
||||
DWORD_PTR dwUser,
|
||||
DWORD_PTR dw1,
|
||||
DWORD_PTR dw2)
|
||||
{
|
||||
int call = -1;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case FADE_IN:
|
||||
if (timeleft == 0)
|
||||
{
|
||||
timeleft = sleep_val;
|
||||
state++;
|
||||
if (SetLayeredWindowAttributesProc != NULL)
|
||||
call = 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
call = ((fadein_val - timeleft) * 255) / fadein_val;
|
||||
break;
|
||||
}
|
||||
case FADE_SLEEP:
|
||||
if (timeleft == 0)
|
||||
{
|
||||
timeleft = fadeout_val;
|
||||
state++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
case FADE_OUT:
|
||||
if (timeleft == 0)
|
||||
{
|
||||
PostMessage((HWND)dwUser, WM_TIMER, 0, 0);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
call = ((timeleft) * 255) / fadeout_val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Transparency value aquired, and could be set...
|
||||
if ((call >= 0) && SetLayeredWindowAttributesProc != NULL)
|
||||
SetLayeredWindowAttributesProc((HWND)dwUser, keycolor,
|
||||
call,
|
||||
alphaparam);
|
||||
// Time is running out...
|
||||
timeleft--;
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
* FUNCTION NAME: play()
|
||||
* PURPOSE:
|
||||
* PlaySound dll entry point
|
||||
* SPECIAL CONSIDERATIONS:
|
||||
* makes PlaySound working on Win98
|
||||
* works with /NOUNLOAD parameter only
|
||||
* wav files are huge :-(
|
||||
* but not flushes on the screen like mci window does
|
||||
* Use it BEFORE 'show' call
|
||||
*****************************************************/
|
||||
extern "C" void __declspec(dllexport) play(HWND hwndParent,
|
||||
int string_size,
|
||||
TCHAR *variables,
|
||||
stack_t **stacktop)
|
||||
{
|
||||
TCHAR fn[MAX_PATH];
|
||||
DWORD snd = SND_FILENAME | SND_ASYNC | SND_NODEFAULT;
|
||||
EXDLL_INIT();
|
||||
if (popstring(fn) == 0)
|
||||
{
|
||||
if (lstrcmpi(fn, _T("/loop")) == 0)
|
||||
{
|
||||
snd |= SND_LOOP;
|
||||
*fn = 0;
|
||||
popstring(fn);
|
||||
}
|
||||
if (*fn == 0)
|
||||
{
|
||||
PlaySound(NULL, NULL, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
PlaySound(fn, NULL, snd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
* FUNCTION NAME: splashThread()
|
||||
* PURPOSE:
|
||||
* modal/modeless banner presentation
|
||||
* SPECIAL CONSIDERATIONS:
|
||||
* from CreateThread runs window "detached", with NULL
|
||||
* parent, otherwise uses current page as parent
|
||||
*****************************************************/
|
||||
DWORD WINAPI splashThread(LPVOID lpParameter)
|
||||
{
|
||||
MSG msg;
|
||||
HWND hParent = (HWND)lpParameter;
|
||||
wc.lpfnWndProc = WndProc;
|
||||
wc.hInstance = g_hInstance;
|
||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wc.lpszClassName = classname;
|
||||
|
||||
if (RegisterClass(&wc))
|
||||
{
|
||||
pIPicture->get_Handle((OLE_HANDLE *)&g_hbm);
|
||||
GetObject((HGDIOBJ)g_hbm, sizeof(BITMAP), &bm);
|
||||
|
||||
myWnd = CreateWindowEx(WS_EX_TOOLWINDOW | (setfg ? WS_EX_TOPMOST : 0) |
|
||||
(SetLayeredWindowAttributesProc != NULL ? WS_EX_LAYERED : 0),
|
||||
classname, classname, 0, 0, 0, 0, 0,
|
||||
hParent, NULL, g_hInstance, NULL);
|
||||
// Set transparency / key color
|
||||
if (SetLayeredWindowAttributesProc != NULL)
|
||||
SetLayeredWindowAttributesProc(myWnd, keycolor,
|
||||
fadein_val > 0 ? 0 : 255,
|
||||
alphaparam);
|
||||
if (keycolor != -1)
|
||||
SetTransparentRegion(myWnd);
|
||||
|
||||
// Start up timer...
|
||||
state = FADE_IN;
|
||||
timeleft = fadein_val;
|
||||
timerEvent = timeSetEvent(resolution, RESOLUTION / 4, TimeProc,
|
||||
(DWORD_PTR)myWnd, TIME_PERIODIC);
|
||||
|
||||
while (IsWindow(myWnd) && GetMessage(&msg, myWnd, 0, 0))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
pIPicture->Release();
|
||||
pIPicture = NULL; // do not re-use with /NOUNLOAD
|
||||
}
|
||||
|
||||
myWnd = NULL;
|
||||
// Stop currently playing wave, we want to exit
|
||||
PlaySound(0, 0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
* FUNCTION NAME: show()
|
||||
* PURPOSE:
|
||||
* image banner "show" dll entry point
|
||||
* SPECIAL CONSIDERATIONS:
|
||||
*
|
||||
*****************************************************/
|
||||
extern "C" void __declspec(dllexport) show(HWND hwndParent,
|
||||
int string_size,
|
||||
TCHAR *variables,
|
||||
stack_t **stacktop)
|
||||
{
|
||||
DEVMODE dm;
|
||||
TCHAR fn[MAX_PATH];
|
||||
WCHAR wcPort[MAX_PATH];
|
||||
DWORD dwThreadId;
|
||||
DWORD dwMainThreadId = GetCurrentThreadId();
|
||||
|
||||
EXDLL_INIT();
|
||||
|
||||
// 3 fade parameters and keycolor from stack come first
|
||||
popstring(fn);
|
||||
sleep_val = _tcstol(fn, NULL, 0);
|
||||
popstring(fn);
|
||||
fadein_val = _tcstol(fn, NULL, 0);
|
||||
popstring(fn);
|
||||
fadeout_val = _tcstol(fn, NULL, 0);
|
||||
popstring(fn);
|
||||
keycolor = _tcstol(fn, NULL, 0);
|
||||
|
||||
// other parameters (if any) + filename
|
||||
while (!popstring(fn) && fn[0] == _T('/'))
|
||||
{
|
||||
if (lstrcmpi(fn, _T("/nocancel")) == 0)
|
||||
nocancel = true;
|
||||
else if (lstrcmpi(fn, _T("/passive")) == 0)
|
||||
setfg = false;
|
||||
else
|
||||
modal = false;
|
||||
}
|
||||
|
||||
if (keycolor == -2)
|
||||
keycolor = getTransparencyColor(fn);
|
||||
|
||||
// Check for winXP/2k at 32 bpp transparency support
|
||||
dm.dmSize = sizeof(DEVMODE);
|
||||
EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm);
|
||||
if (dm.dmBitsPerPel >= 32)
|
||||
{
|
||||
HANDLE user32 = GetModuleHandle(_T("user32"));
|
||||
SetLayeredWindowAttributesProc = (_tSetLayeredWindowAttributesProc)
|
||||
GetProcAddress((HINSTANCE)user32, "SetLayeredWindowAttributes");
|
||||
}
|
||||
|
||||
if (SetLayeredWindowAttributesProc == NULL)
|
||||
{
|
||||
// Fading+transparency is unsupported at old windows versions...
|
||||
resolution = (sleep_val + fadein_val + fadeout_val) / 2;
|
||||
fadeout_val = fadein_val = 0;
|
||||
sleep_val = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// div them by resolution - now times are in 32 ms "frames"
|
||||
sleep_val >>= 5;
|
||||
fadein_val >>= 5;
|
||||
fadeout_val >>= 5;
|
||||
// MS RGB - BGR format
|
||||
alphaparam = LWA_ALPHA | (keycolor == -1 ? 0 : LWA_COLORKEY);
|
||||
if (keycolor != -1)
|
||||
keycolor = ((keycolor & 0xFF) << 16) + (keycolor & 0xFF00) +
|
||||
((keycolor & 0xFF0000) >> 16);
|
||||
}
|
||||
|
||||
// who wrote this script :-))
|
||||
#ifdef _UNICODE
|
||||
lstrcpy(wcPort, fn);
|
||||
#else
|
||||
MultiByteToWideChar(CP_ACP, 0, fn, -1, wcPort, sizeof(wcPort) / 2);
|
||||
#endif
|
||||
OleLoadPicturePath((LPOLESTR)wcPort, 0, 0, 0, IID_IPicture, (void **)&pIPicture);
|
||||
if (pIPicture == NULL ||
|
||||
(sleep_val + fadein_val + fadeout_val) <= 0)
|
||||
return;
|
||||
|
||||
if (modal)
|
||||
{
|
||||
splashThread((void *)hwndParent);
|
||||
// We should UnRegister class, since Windows NT series never does this by itself
|
||||
UnregisterClass(wc.lpszClassName, g_hInstance);
|
||||
}
|
||||
else
|
||||
{
|
||||
// start thread and wait for window initialization
|
||||
hThread = CreateThread(0, 0, splashThread, NULL, 0, &dwThreadId);
|
||||
while (myWnd == NULL || !IsWindowVisible(myWnd))
|
||||
Sleep(10);
|
||||
if (setfg)
|
||||
sf(myWnd);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
* FUNCTION NAME: stop()
|
||||
* PURPOSE:
|
||||
* image banner "stop" dll entry point
|
||||
* SPECIAL CONSIDERATIONS:
|
||||
*
|
||||
*****************************************************/
|
||||
extern "C" void __declspec(dllexport) stop(HWND hwndParent,
|
||||
int string_size,
|
||||
TCHAR *variables,
|
||||
stack_t **stacktop)
|
||||
{
|
||||
TCHAR cmd[64];
|
||||
if (!modal && hThread != NULL)
|
||||
{
|
||||
if (popstring(cmd) == 0)
|
||||
{
|
||||
if (lstrcmpi(cmd, _T("/fadeout")) == 0)
|
||||
{
|
||||
if (SetLayeredWindowAttributesProc == NULL)
|
||||
stop(hwndParent, string_size, variables, stacktop);
|
||||
else
|
||||
{
|
||||
if (state == FADE_IN)
|
||||
{
|
||||
sleep_val = 1; // minimize sleep step - 1 frame only
|
||||
}
|
||||
else if (state == FADE_SLEEP)
|
||||
{
|
||||
timeleft = 1; // force sleep to finish
|
||||
}
|
||||
WaitForSingleObject(hThread, (fadein_val + fadeout_val + 3) * resolution);
|
||||
}
|
||||
}
|
||||
if (lstrcmpi(cmd, _T("/wait")) == 0)
|
||||
{
|
||||
WaitForSingleObject(hThread,
|
||||
resolution * (SetLayeredWindowAttributesProc == NULL ? 2 : fadein_val + fadeout_val + sleep_val + 3));
|
||||
}
|
||||
else
|
||||
pushstring(cmd); // this is not our string
|
||||
}
|
||||
if (IsWindow(myWnd))
|
||||
{
|
||||
SendMessage(myWnd, WM_TIMER, 0, 0); // stops sound and destroys window
|
||||
}
|
||||
WaitForSingleObject(hThread, 1000);
|
||||
CloseHandle(hThread);
|
||||
hThread = NULL;
|
||||
|
||||
// hbatista
|
||||
UnregisterClass(wc.lpszClassName, g_hInstance);
|
||||
Sleep(10);
|
||||
if (setfg)
|
||||
sf(hwndParent);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
* FUNCTION NAME: hwnd()
|
||||
* PURPOSE:
|
||||
* retrieves target window handle
|
||||
* SPECIAL CONSIDERATIONS:
|
||||
*
|
||||
*****************************************************/
|
||||
extern "C" void __declspec(dllexport) hwnd(HWND hwndParent,
|
||||
int string_size,
|
||||
TCHAR *variables,
|
||||
stack_t **stacktop)
|
||||
{
|
||||
TCHAR s[16] = _T("");
|
||||
if (IsWindow(myWnd))
|
||||
wsprintf(s, _T("%d"), myWnd);
|
||||
pushstring(s);
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
* FUNCTION NAME: DllMain()
|
||||
* PURPOSE:
|
||||
* Dll main (initialization) entry point
|
||||
* SPECIAL CONSIDERATIONS:
|
||||
*
|
||||
*****************************************************/
|
||||
BOOL WINAPI DllMain(HANDLE hInst,
|
||||
ULONG ul_reason_for_call,
|
||||
LPVOID lpReserved)
|
||||
{
|
||||
g_hInstance = (HINSTANCE)hInst;
|
||||
return TRUE;
|
||||
}
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
#ifndef _EXDLL_H_
|
||||
#define _EXDLL_H_
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
// only include this file from one place in your DLL.
|
||||
// (it is all static, if you use it in two places it will fail)
|
||||
|
||||
#define EXDLL_INIT() \
|
||||
{ \
|
||||
g_stringsize = string_size; \
|
||||
g_stacktop = stacktop; \
|
||||
g_variables = variables; \
|
||||
}
|
||||
|
||||
// For page showing plug-ins
|
||||
#define WM_NOTIFY_OUTER_NEXT (WM_USER + 0x8)
|
||||
#define WM_NOTIFY_CUSTOM_READY (WM_USER + 0xd)
|
||||
#define NOTIFY_BYE_BYE 'x'
|
||||
|
||||
typedef struct _stack_t
|
||||
{
|
||||
struct _stack_t *next;
|
||||
TCHAR text[1]; // this should be the length of string_size
|
||||
} stack_t;
|
||||
|
||||
static unsigned int g_stringsize;
|
||||
static stack_t **g_stacktop;
|
||||
static TCHAR *g_variables;
|
||||
|
||||
enum
|
||||
{
|
||||
INST_0, // $0
|
||||
INST_1, // $1
|
||||
INST_2, // $2
|
||||
INST_3, // $3
|
||||
INST_4, // $4
|
||||
INST_5, // $5
|
||||
INST_6, // $6
|
||||
INST_7, // $7
|
||||
INST_8, // $8
|
||||
INST_9, // $9
|
||||
INST_R0, // $R0
|
||||
INST_R1, // $R1
|
||||
INST_R2, // $R2
|
||||
INST_R3, // $R3
|
||||
INST_R4, // $R4
|
||||
INST_R5, // $R5
|
||||
INST_R6, // $R6
|
||||
INST_R7, // $R7
|
||||
INST_R8, // $R8
|
||||
INST_R9, // $R9
|
||||
INST_CMDLINE, // $CMDLINE
|
||||
INST_INSTDIR, // $INSTDIR
|
||||
INST_OUTDIR, // $OUTDIR
|
||||
INST_EXEDIR, // $EXEDIR
|
||||
INST_LANG, // $LANGUAGE
|
||||
__INST_LAST
|
||||
};
|
||||
|
||||
// utility functions (not required but often useful)
|
||||
static int __stdcall popstring(TCHAR *str)
|
||||
{
|
||||
stack_t *th;
|
||||
if (!g_stacktop || !*g_stacktop)
|
||||
return 1;
|
||||
th = (*g_stacktop);
|
||||
lstrcpy(str, th->text);
|
||||
*g_stacktop = th->next;
|
||||
GlobalFree((HGLOBAL)th);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __stdcall pushstring(const TCHAR *str)
|
||||
{
|
||||
stack_t *th;
|
||||
if (!g_stacktop)
|
||||
return;
|
||||
th = (stack_t *)GlobalAlloc(GPTR, sizeof(stack_t) + g_stringsize * sizeof(TCHAR));
|
||||
lstrcpyn(th->text, str, g_stringsize);
|
||||
th->next = *g_stacktop;
|
||||
*g_stacktop = th;
|
||||
}
|
||||
|
||||
static TCHAR *__stdcall getuservariable(int varnum)
|
||||
{
|
||||
if (varnum < 0 || varnum >= __INST_LAST)
|
||||
return NULL;
|
||||
return g_variables + varnum * g_stringsize;
|
||||
}
|
||||
|
||||
static void __stdcall setuservariable(int varnum, const TCHAR *var)
|
||||
{
|
||||
if (varnum < 0 || varnum >= __INST_LAST)
|
||||
return;
|
||||
lstrcpy(g_variables + varnum * g_stringsize, var);
|
||||
}
|
||||
|
||||
#endif //_EXDLL_H_
|
||||
+257
@@ -0,0 +1,257 @@
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
// My gratitute to Andy Key. His GBM lib served as a base
|
||||
// for this short gif decoder. I only added extraction
|
||||
// of transparansy color and comments.
|
||||
// Takhir
|
||||
|
||||
#define byte unsigned char
|
||||
#define word unsigned short
|
||||
|
||||
#define make_word(a,b) (((word)a) + (((word)b) << 8))
|
||||
|
||||
|
||||
typedef int GBM_ERR;
|
||||
|
||||
#define GBM_ERR_GIF_BPP ((GBM_ERR) 1100)
|
||||
#define GBM_ERR_GIF_TERM ((GBM_ERR) 1101)
|
||||
#define GBM_ERR_GIF_CODE_SIZE ((GBM_ERR) 1102)
|
||||
#define GBM_ERR_GIF_CORRUPT ((GBM_ERR) 1103)
|
||||
#define GBM_ERR_GIF_HEADER ((GBM_ERR) 1104)
|
||||
|
||||
#define GBM_ERR_OK ((GBM_ERR) 0)
|
||||
#define GBM_ERR_BAD_MAGIC ((GBM_ERR) 5)
|
||||
#define GBM_ERR_READ ((GBM_ERR) 7)
|
||||
#define GBM_ERR_WRITE ((GBM_ERR) 8)
|
||||
|
||||
|
||||
|
||||
typedef unsigned int cword;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BOOLEAN ilace, errok;
|
||||
int bpp;
|
||||
byte pal[0x100*3];
|
||||
} GIF_PRIV;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int fd; /* File descriptor to read */
|
||||
int inx, size; /* Index and size in bits */
|
||||
byte buf[255+3]; /* Buffer holding bits */
|
||||
int code_size; /* Number of bits to return at once */
|
||||
cword read_mask; /* 2^code_size-1 */
|
||||
} READ_CONTEXT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int x, y, w, h, bpp, pass;
|
||||
BOOLEAN ilace;
|
||||
int stride;
|
||||
byte *data, *data_this_line;
|
||||
} OUTPUT_CONTEXT;
|
||||
|
||||
typedef unsigned int cword;
|
||||
|
||||
typedef struct { byte r, g, b; } GBMRGB;
|
||||
|
||||
#define PRIV_SIZE 2000
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int w, h, bpp; /* Bitmap dimensions */
|
||||
byte priv[PRIV_SIZE]; /* Private internal buffer */
|
||||
int trc;
|
||||
char *szUrl;
|
||||
} GBM;
|
||||
|
||||
|
||||
|
||||
|
||||
/*...sgif_rhdr:0:*/
|
||||
GBM_ERR gif_rhdr(int fd, GBM *gbm)
|
||||
{
|
||||
GIF_PRIV *gif_priv = (GIF_PRIV *) gbm->priv;
|
||||
byte signiture[6], scn_desc[7], image_desc[10];
|
||||
int img = -1, img_want = 0;
|
||||
int bits_gct;
|
||||
|
||||
/* Read and validate signiture block */
|
||||
|
||||
if ( _read(fd, signiture, 6) != 6 )
|
||||
return GBM_ERR_READ;
|
||||
if ( memcmp(signiture, "GIF87a", 6) &&
|
||||
memcmp(signiture, "GIF89a", 6) )
|
||||
return GBM_ERR_BAD_MAGIC;
|
||||
|
||||
/* Read screen descriptor */
|
||||
|
||||
if ( _read(fd, scn_desc, 7) != 7 )
|
||||
return GBM_ERR_READ;
|
||||
bits_gct = gif_priv->bpp = (scn_desc[4] & 7) + 1;
|
||||
// bits_gct = ((scn_desc[4] & 0x70) >> 4) + 1;
|
||||
|
||||
if ( scn_desc[4] & 0x80 )
|
||||
/* Global colour table follows screen descriptor */
|
||||
{
|
||||
if ( _read(fd, gif_priv->pal, 3 << bits_gct) != (3 << bits_gct) )
|
||||
return GBM_ERR_READ;
|
||||
}
|
||||
else
|
||||
/* Blank out palette, but make entry 1 white */
|
||||
{
|
||||
memset(gif_priv->pal, 0, 3 << bits_gct);
|
||||
gif_priv->pal[3] =
|
||||
gif_priv->pal[4] =
|
||||
gif_priv->pal[5] = 0xff;
|
||||
}
|
||||
|
||||
/* Expected image descriptors / extension blocks / terminator */
|
||||
|
||||
while ( img < img_want )
|
||||
{
|
||||
if ( _read(fd, image_desc, 1) != 1 )
|
||||
return GBM_ERR_READ;
|
||||
switch ( image_desc[0] )
|
||||
{
|
||||
/*...s0x2c \45\ image descriptor:24:*/
|
||||
case 0x2c:
|
||||
if ( _read(fd, image_desc + 1, 9) != 9 )
|
||||
return GBM_ERR_READ;
|
||||
gbm->w = make_word(image_desc[5], image_desc[6]);
|
||||
gbm->h = make_word(image_desc[7], image_desc[8]);
|
||||
gif_priv->ilace = ( (image_desc[9] & 0x40) != 0 );
|
||||
|
||||
if ( image_desc[9] & 0x80 )
|
||||
/* Local colour table follows */
|
||||
{
|
||||
gif_priv->bpp = (image_desc[9] & 7) + 1;
|
||||
if ( _read(fd, gif_priv->pal, 3 << gif_priv->bpp) != (3 << gif_priv->bpp) )
|
||||
return GBM_ERR_READ;
|
||||
}
|
||||
|
||||
if ( ++img != img_want )
|
||||
/* Skip the image data */
|
||||
{
|
||||
byte code_size, block_size;
|
||||
|
||||
if ( _read(fd, &code_size, 1) != 1 )
|
||||
return GBM_ERR_READ;
|
||||
do
|
||||
{
|
||||
if ( _read(fd, &block_size, 1) != 1 )
|
||||
return GBM_ERR_READ;
|
||||
_lseek(fd, block_size, SEEK_CUR);
|
||||
}
|
||||
while ( block_size );
|
||||
}
|
||||
|
||||
break;
|
||||
/*...e*/
|
||||
/*...s0x21 \45\ extension block:24:*/
|
||||
/* Ignore all extension blocks */
|
||||
|
||||
case 0x21:
|
||||
{
|
||||
/* Graphics and Comment ControlExtensions added by Takhir */
|
||||
byte func_code, byte_count, rslt;
|
||||
if ( _read(fd, &func_code, 1) != 1 )
|
||||
return GBM_ERR_READ;
|
||||
_read(fd, &byte_count, 1);
|
||||
switch (func_code)
|
||||
{
|
||||
case 0xF9: // GraphicsControlExtensions
|
||||
byte_count++;
|
||||
for(;byte_count>0;byte_count--)
|
||||
{
|
||||
if ( _read(fd, &rslt, 1) != 1 )
|
||||
return GBM_ERR_READ;
|
||||
if((byte_count==5)&&(rslt&1)) gbm->trc=1;
|
||||
if((byte_count==2)&&(gbm->trc==1))
|
||||
gbm->trc=rslt;
|
||||
}
|
||||
break;
|
||||
case 0xFE: // CommentControlExtensions
|
||||
if(gbm->szUrl==NULL)
|
||||
_lseek(fd, byte_count+1, SEEK_CUR);
|
||||
else
|
||||
{
|
||||
gbm->szUrl[0] = 0;
|
||||
if (_read(fd, gbm->szUrl, byte_count+1) != ((int)byte_count+1) )
|
||||
return GBM_ERR_READ;
|
||||
}
|
||||
break;
|
||||
default: // Other Extensions
|
||||
do
|
||||
{ _lseek(fd, byte_count, SEEK_CUR);
|
||||
if ( _read(fd, &byte_count, 1) != 1 )
|
||||
return GBM_ERR_READ;
|
||||
}
|
||||
while ( byte_count );
|
||||
}
|
||||
/* end of changes */
|
||||
}
|
||||
break;
|
||||
/*...e*/
|
||||
/*...s0x3b \45\ terminator:24:*/
|
||||
/* Oi, we were hoping to get an image descriptor! */
|
||||
|
||||
case 0x3b:
|
||||
return GBM_ERR_GIF_TERM;
|
||||
/*...e*/
|
||||
/*...sdefault:24:*/
|
||||
default:
|
||||
return GBM_ERR_GIF_HEADER;
|
||||
/*...e*/
|
||||
}
|
||||
}
|
||||
|
||||
switch ( gif_priv->bpp )
|
||||
{
|
||||
case 1: gbm->bpp = 1; break;
|
||||
case 2:
|
||||
case 3:
|
||||
case 4: gbm->bpp = 4; break;
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8: gbm->bpp = 8; break;
|
||||
default: return GBM_ERR_GIF_BPP;
|
||||
}
|
||||
|
||||
return GBM_ERR_OK;
|
||||
}
|
||||
|
||||
/*...e*/
|
||||
/*...sgif_rdata:0:*/
|
||||
/*...sread context:0:*/
|
||||
|
||||
|
||||
int getTransparencyColor(TCHAR* fn_src)
|
||||
{
|
||||
int fd;
|
||||
GBM gbm;
|
||||
GBMRGB *gbmrgb = (GBMRGB*)(gbm.priv + 8);
|
||||
|
||||
if(lstrcmpi(fn_src + lstrlen(fn_src) - 4, _T(".gif")) != 0) return -1;
|
||||
gbm.trc = -1;
|
||||
gbm.szUrl = NULL;
|
||||
if ((fd = _topen(fn_src, O_RDONLY | O_BINARY))==-1) return 0;
|
||||
gif_rhdr( fd, &gbm);
|
||||
_close(fd);
|
||||
if(gbm.trc == -1 || gbm.trc > 255) return -1;
|
||||
fd = 0;
|
||||
memcpy(&fd, &gbmrgb[gbm.trc], 3);
|
||||
/*char b[64];
|
||||
wsprintf(b, "Index %d, color=0x%06x", gbm.trc, fd);
|
||||
MessageBox(NULL, b, "Index & color", 0);*/
|
||||
return fd;
|
||||
}
|
||||
Reference in New Issue
Block a user