mirror of
https://github.com/zs-yg/kortapp-z.git
synced 2025-12-06 16:10:42 +08:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5651e944f9 | ||
|
|
1dbd9968c9 | ||
|
|
e387d22fee | ||
|
|
68bd471bd2 | ||
|
|
53392a2ce8 | ||
|
|
5ecfe2da2a | ||
|
|
5b9532acfe | ||
|
|
c87d071ee0 |
@@ -50,7 +50,7 @@ namespace AppStore
|
|||||||
|
|
||||||
// 初始化并添加应用信息
|
// 初始化并添加应用信息
|
||||||
infoLabel = new Label();
|
infoLabel = new Label();
|
||||||
infoLabel.Text = "kortapp-z\n版本: 1.0.8\n作者: zs-yg\n一个简单、开源的应用商店\nkortapp-z是完全免费\n基于.NET8和C/C++的软件";
|
infoLabel.Text = "kortapp-z\n版本: 1.1.0\n作者: zs-yg\n一个简单、开源的应用商店\nkortapp-z是完全免费\n基于.NET8和C/C++的软件";
|
||||||
infoLabel.Font = new Font("Microsoft YaHei", 12);
|
infoLabel.Font = new Font("Microsoft YaHei", 12);
|
||||||
infoLabel.AutoSize = false;
|
infoLabel.AutoSize = false;
|
||||||
infoLabel.Width = 300;
|
infoLabel.Width = 300;
|
||||||
|
|||||||
53
MainForm.cs
53
MainForm.cs
@@ -501,6 +501,59 @@ namespace AppStore
|
|||||||
}
|
}
|
||||||
flowPanel.Controls.Add(calculatorCard);
|
flowPanel.Controls.Add(calculatorCard);
|
||||||
|
|
||||||
|
// 图片查看工具卡片
|
||||||
|
var imageViewerCard = new KortAppZ.Tools.Viewer.ImageViewerToolCard();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string iconPath = Path.Combine(Application.StartupPath, "img", "resource", "png", "ImageCompressor.png");
|
||||||
|
if (File.Exists(iconPath))
|
||||||
|
{
|
||||||
|
imageViewerCard.ToolIcon = Image.FromFile(iconPath);
|
||||||
|
}
|
||||||
|
imageViewerCard.UpdateDisplay();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.LogError("加载图片查看器图标失败", ex);
|
||||||
|
}
|
||||||
|
flowPanel.Controls.Add(imageViewerCard);
|
||||||
|
|
||||||
|
// 密码生成器工具卡片
|
||||||
|
var passwordGeneratorCard = new ToolCard();
|
||||||
|
passwordGeneratorCard.ToolName = "密码生成器";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string iconPath = Path.Combine(Application.StartupPath, "img", "resource", "png", "password_generator.png");
|
||||||
|
if (File.Exists(iconPath))
|
||||||
|
{
|
||||||
|
passwordGeneratorCard.ToolIcon = Image.FromFile(iconPath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
passwordGeneratorCard.ToolIcon = SystemIcons.Shield.ToBitmap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
passwordGeneratorCard.ToolIcon = SystemIcons.Shield.ToBitmap();
|
||||||
|
}
|
||||||
|
passwordGeneratorCard.ToolCardClicked += (s, e) => {
|
||||||
|
try {
|
||||||
|
string toolPath = Path.Combine(Application.StartupPath, "resource", "password_generator.exe");
|
||||||
|
if (File.Exists(toolPath)) {
|
||||||
|
Process.Start(toolPath);
|
||||||
|
} else {
|
||||||
|
MessageBox.Show("密码生成器工具未找到,请确保已正确安装", "错误",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
MessageBox.Show($"启动密码生成器失败: {ex.Message}", "错误",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
passwordGeneratorCard.UpdateDisplay();
|
||||||
|
flowPanel.Controls.Add(passwordGeneratorCard);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -35,14 +35,15 @@
|
|||||||
|
|
||||||
### 打包指令
|
### 打包指令
|
||||||
|
|
||||||
|
|
||||||
#### 32位版本
|
#### 32位版本
|
||||||
```bash
|
```bash
|
||||||
dotnet publish -c Release -r win-x86 -p:PublishSingleFile=true
|
dotnet publish AppStore.csproj -c Release -r win-x86 --self-contained false /p:Optimize=true /p:DebugType=None
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 64位版本
|
#### 64位版本
|
||||||
```bash
|
```bash
|
||||||
dotnet publish -c Release -r win-x64 -p:PublishSingleFile=true
|
dotnet publish AppStore.csproj -c Release -r win-x64 --self-contained false /p:Optimize=true /p:DebugType=None
|
||||||
```
|
```
|
||||||
|
|
||||||
打包后的可执行文件将包含指定的应用程序图标,输出路径为:
|
打包后的可执行文件将包含指定的应用程序图标,输出路径为:
|
||||||
@@ -51,7 +52,9 @@ bin\Release\net8.0-windows\[platform]\publish
|
|||||||
```
|
```
|
||||||
|
|
||||||
### 高级选项
|
### 高级选项
|
||||||
- 添加`--self-contained true`可生成独立包(体积较大)
|
- 使用`--self-contained false`生成框架依赖包(默认)
|
||||||
|
- 使用`/p:Optimize=true`启用代码优化(默认)
|
||||||
|
- 使用`/p:DebugType=None`禁用调试符号生成(默认)
|
||||||
- 添加`-p:PublishTrimmed=true`可减小包体积(实验性)
|
- 添加`-p:PublishTrimmed=true`可减小包体积(实验性)
|
||||||
|
|
||||||
## 项目结构
|
## 项目结构
|
||||||
|
|||||||
12
TXT/Build.txt
Normal file
12
TXT/Build.txt
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
首先,如果希望编译程序,那么必须安装.NET8.0 SDK
|
||||||
|
下载链接:https://dotnet.microsoft.com/zh-cn/download/dotnet/thank-you/sdk-8.0.411-windows-x64-installer
|
||||||
|
|
||||||
|
使用一下指令编译
|
||||||
|
|
||||||
|
x86:
|
||||||
|
|
||||||
|
dotnet publish AppStore.csproj -c Release -r win-x86 --self-contained false /p:Optimize=true /p:DebugType=None
|
||||||
|
|
||||||
|
x64:
|
||||||
|
|
||||||
|
dotnet publish AppStore.csproj -c Release -r win-x64 --self-contained false /p:Optimize=true /p:DebugType=None
|
||||||
7
TXT/Run.txt
Normal file
7
TXT/Run.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
如果希望运行,那么必须安装.NET8.0 SDK
|
||||||
|
|
||||||
|
下载链接:https://dotnet.microsoft.com/zh-cn/download/dotnet/thank-you/sdk-8.0.411-windows-x64-installer
|
||||||
|
|
||||||
|
使用一下指令运行:
|
||||||
|
|
||||||
|
dotnet run
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
; 有关创建 Inno Setup 脚本文件的详细信息,请参阅帮助文档!
|
; 有关创建 Inno Setup 脚本文件的详细信息,请参阅帮助文档!
|
||||||
|
|
||||||
#define MyAppName "kortapp-z"
|
#define MyAppName "kortapp-z"
|
||||||
#define MyAppVersion "1.0.8"
|
#define MyAppVersion "1.1.0"
|
||||||
#define MyAppPublisher "zsyg"
|
#define MyAppPublisher "zsyg"
|
||||||
#define MyAppURL "https://github.com/zs-yg/kortapp-z"
|
#define MyAppURL "https://github.com/zs-yg/kortapp-z"
|
||||||
#define MyAppExeName "kortapp.exe"
|
#define MyAppExeName "kortapp.exe"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
; 有关创建 Inno Setup 脚本文件的详细信息,请参阅帮助文档!
|
; 有关创建 Inno Setup 脚本文件的详细信息,请参阅帮助文档!
|
||||||
|
|
||||||
#define MyAppName "kortapp-z"
|
#define MyAppName "kortapp-z"
|
||||||
#define MyAppVersion "1.0.8"
|
#define MyAppVersion "1.1.0"
|
||||||
#define MyAppPublisher "zsyg"
|
#define MyAppPublisher "zsyg"
|
||||||
#define MyAppURL "https://github.com/zs-yg/kortapp-z"
|
#define MyAppURL "https://github.com/zs-yg/kortapp-z"
|
||||||
#define MyAppExeName "kortapp.exe"
|
#define MyAppExeName "kortapp.exe"
|
||||||
|
|||||||
20
others/C/C++/Makefile
Normal file
20
others/C/C++/Makefile
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
CXX = g++
|
||||||
|
CXXFLAGS = -std=c++11 -Iinclude
|
||||||
|
LDFLAGS = -static -mwindows -lfltk -lole32 -luuid -lcomctl32 -lgdi32 -lwsock32 -lcomdlg32 -lwinspool
|
||||||
|
|
||||||
|
SRC = $(wildcard src/*.cpp)
|
||||||
|
OBJ = $(patsubst src/%.cpp,obj/%.o,$(SRC))
|
||||||
|
TARGET = password_generator
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
$(TARGET): $(OBJ)
|
||||||
|
$(CXX) $^ -o $@ $(LDFLAGS)
|
||||||
|
|
||||||
|
obj/%.o: src/%.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(OBJ) $(TARGET)
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
27
others/C/C++/include/password_generator.hpp
Normal file
27
others/C/C++/include/password_generator.hpp
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#ifndef PASSWORD_GENERATOR_HPP
|
||||||
|
#define PASSWORD_GENERATOR_HPP
|
||||||
|
|
||||||
|
#include "string.hpp"
|
||||||
|
|
||||||
|
class PasswordGenerator {
|
||||||
|
public:
|
||||||
|
enum Mode {
|
||||||
|
DIGITS, // 纯数字
|
||||||
|
ENGLISH, // 纯英文
|
||||||
|
SYMBOLS, // 纯符号
|
||||||
|
DIGITS_ENGLISH, // 数字+英文
|
||||||
|
DIGITS_SYMBOLS, // 数字+符号
|
||||||
|
ENGLISH_SYMBOLS // 英文+符号
|
||||||
|
};
|
||||||
|
|
||||||
|
PasswordGenerator();
|
||||||
|
String generate(int length, Mode mode = DIGITS);
|
||||||
|
|
||||||
|
private:
|
||||||
|
String generateDigits(int length);
|
||||||
|
String generateEnglish(int length);
|
||||||
|
String generateSymbols(int length);
|
||||||
|
String generateMixed(int length, const String& charSet);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PASSWORD_GENERATOR_HPP
|
||||||
28
others/C/C++/include/password_gui.hpp
Normal file
28
others/C/C++/include/password_gui.hpp
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef PASSWORD_GUI_HPP
|
||||||
|
#define PASSWORD_GUI_HPP
|
||||||
|
|
||||||
|
#include <FL/Fl.H>
|
||||||
|
#include <FL/Fl_Window.H>
|
||||||
|
#include <FL/Fl_Input.H>
|
||||||
|
#include <FL/Fl_Choice.H>
|
||||||
|
#include <FL/Fl_Button.H>
|
||||||
|
#include <FL/Fl_Output.H>
|
||||||
|
#include "password_generator.hpp"
|
||||||
|
|
||||||
|
class PasswordGUI {
|
||||||
|
public:
|
||||||
|
PasswordGUI();
|
||||||
|
void show();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Fl_Window* window;
|
||||||
|
Fl_Input* lengthInput;
|
||||||
|
Fl_Choice* modeChoice;
|
||||||
|
Fl_Button* generateButton;
|
||||||
|
Fl_Output* passwordOutput;
|
||||||
|
PasswordGenerator generator;
|
||||||
|
|
||||||
|
static void onGenerate(Fl_Widget* widget, void* data);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PASSWORD_GUI_HPP
|
||||||
25
others/C/C++/include/string.hpp
Normal file
25
others/C/C++/include/string.hpp
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef STRING_HPP
|
||||||
|
#define STRING_HPP
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
class String {
|
||||||
|
public:
|
||||||
|
String();
|
||||||
|
String(const char* str);
|
||||||
|
String(const String& other);
|
||||||
|
~String();
|
||||||
|
|
||||||
|
size_t length() const;
|
||||||
|
const char* c_str() const;
|
||||||
|
|
||||||
|
String& operator=(const String& other);
|
||||||
|
String operator+(const String& other) const;
|
||||||
|
bool operator==(const String& other) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
char* data;
|
||||||
|
size_t len;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // STRING_HPP
|
||||||
7
others/C/C++/src/main.cpp
Normal file
7
others/C/C++/src/main.cpp
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#include "password_gui.hpp"
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
PasswordGUI gui;
|
||||||
|
gui.show();
|
||||||
|
return Fl::run();
|
||||||
|
}
|
||||||
96
others/C/C++/src/password_generator.cpp
Normal file
96
others/C/C++/src/password_generator.cpp
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
#include "password_generator.hpp"
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
PasswordGenerator::PasswordGenerator() {
|
||||||
|
srand(time(nullptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
String PasswordGenerator::generate(int length, Mode mode) {
|
||||||
|
if (length < 1 || length > 100) {
|
||||||
|
return String("无效长度(1-100)");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case DIGITS:
|
||||||
|
return generateDigits(length);
|
||||||
|
case ENGLISH:
|
||||||
|
return generateEnglish(length);
|
||||||
|
case SYMBOLS:
|
||||||
|
return generateSymbols(length);
|
||||||
|
case DIGITS_ENGLISH: {
|
||||||
|
String charSet = String("0123456789") +
|
||||||
|
String("abcdefghijklmnopqrstuvwxyz") +
|
||||||
|
String("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||||
|
return generateMixed(length, charSet);
|
||||||
|
}
|
||||||
|
case DIGITS_SYMBOLS: {
|
||||||
|
String charSet = String("0123456789") + String("!@#$%^&*()_+-=[]{}|;:,.<>?");
|
||||||
|
return generateMixed(length, charSet);
|
||||||
|
}
|
||||||
|
case ENGLISH_SYMBOLS: {
|
||||||
|
String charSet = String("abcdefghijklmnopqrstuvwxyz") +
|
||||||
|
String("ABCDEFGHIJKLMNOPQRSTUVWXYZ") +
|
||||||
|
String("!@#$%^&*()_+-=[]{}|;:,.<>?");
|
||||||
|
return generateMixed(length, charSet);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return String("不支持的模式");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String PasswordGenerator::generateDigits(int length) {
|
||||||
|
char* buffer = new char[length + 1];
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
|
buffer[i] = '0' + (rand() % 10);
|
||||||
|
}
|
||||||
|
buffer[length] = '\0';
|
||||||
|
|
||||||
|
String result(buffer);
|
||||||
|
delete[] buffer;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
String PasswordGenerator::generateEnglish(int length) {
|
||||||
|
char* buffer = new char[length + 1];
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
|
int choice = rand() % 2;
|
||||||
|
if (choice == 0) {
|
||||||
|
buffer[i] = 'a' + (rand() % 26); // 小写字母
|
||||||
|
} else {
|
||||||
|
buffer[i] = 'A' + (rand() % 26); // 大写字母
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer[length] = '\0';
|
||||||
|
|
||||||
|
String result(buffer);
|
||||||
|
delete[] buffer;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
String PasswordGenerator::generateSymbols(int length) {
|
||||||
|
const char symbols[] = "!@#$%^&*()_+-=[]{}|;:,.<>?";
|
||||||
|
const int symbolCount = sizeof(symbols) - 1; // 减去末尾的\0
|
||||||
|
|
||||||
|
char* buffer = new char[length + 1];
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
|
buffer[i] = symbols[rand() % symbolCount];
|
||||||
|
}
|
||||||
|
buffer[length] = '\0';
|
||||||
|
|
||||||
|
String result(buffer);
|
||||||
|
delete[] buffer;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
String PasswordGenerator::generateMixed(int length, const String& charSet) {
|
||||||
|
char* buffer = new char[length + 1];
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
|
buffer[i] = charSet.c_str()[rand() % charSet.length()];
|
||||||
|
}
|
||||||
|
buffer[length] = '\0';
|
||||||
|
|
||||||
|
String result(buffer);
|
||||||
|
delete[] buffer;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
36
others/C/C++/src/password_gui.cpp
Normal file
36
others/C/C++/src/password_gui.cpp
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#include "password_gui.hpp"
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
PasswordGUI::PasswordGUI() {
|
||||||
|
window = new Fl_Window(400, 350, "密码生成器");
|
||||||
|
|
||||||
|
lengthInput = new Fl_Input(150, 50, 200, 30, "密码长度:");
|
||||||
|
modeChoice = new Fl_Choice(150, 90, 200, 30, "密码模式:");
|
||||||
|
modeChoice->add("纯数字");
|
||||||
|
modeChoice->add("纯英文");
|
||||||
|
modeChoice->add("纯符号");
|
||||||
|
modeChoice->add("数字+英文");
|
||||||
|
modeChoice->add("数字+符号");
|
||||||
|
modeChoice->add("英文+符号");
|
||||||
|
modeChoice->value(0); // 默认选择纯数字模式
|
||||||
|
|
||||||
|
generateButton = new Fl_Button(150, 140, 100, 40, "生成密码");
|
||||||
|
passwordOutput = new Fl_Output(100, 210, 250, 40, "生成结果:");
|
||||||
|
|
||||||
|
generateButton->callback(onGenerate, this);
|
||||||
|
window->end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PasswordGUI::show() {
|
||||||
|
window->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PasswordGUI::onGenerate(Fl_Widget* widget, void* data) {
|
||||||
|
PasswordGUI* gui = static_cast<PasswordGUI*>(data);
|
||||||
|
const char* lengthStr = gui->lengthInput->value();
|
||||||
|
int length = atoi(lengthStr);
|
||||||
|
|
||||||
|
PasswordGenerator::Mode mode = static_cast<PasswordGenerator::Mode>(gui->modeChoice->value());
|
||||||
|
String password = gui->generator.generate(length, mode);
|
||||||
|
gui->passwordOutput->value(password.c_str());
|
||||||
|
}
|
||||||
51
others/C/C++/src/string.cpp
Normal file
51
others/C/C++/src/string.cpp
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#include "string.hpp"
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
String::String() : data(nullptr), len(0) {}
|
||||||
|
|
||||||
|
String::String(const char* str) {
|
||||||
|
len = strlen(str);
|
||||||
|
data = new char[len + 1];
|
||||||
|
strcpy(data, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
String::String(const String& other) {
|
||||||
|
len = other.len;
|
||||||
|
data = new char[len + 1];
|
||||||
|
strcpy(data, other.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
String::~String() {
|
||||||
|
delete[] data;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t String::length() const {
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* String::c_str() const {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
String& String::operator=(const String& other) {
|
||||||
|
if (this != &other) {
|
||||||
|
delete[] data;
|
||||||
|
len = other.len;
|
||||||
|
data = new char[len + 1];
|
||||||
|
strcpy(data, other.data);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
String String::operator+(const String& other) const {
|
||||||
|
String result;
|
||||||
|
result.len = len + other.len;
|
||||||
|
result.data = new char[result.len + 1];
|
||||||
|
strcpy(result.data, data);
|
||||||
|
strcat(result.data, other.data);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool String::operator==(const String& other) const {
|
||||||
|
return strcmp(data, other.data) == 0;
|
||||||
|
}
|
||||||
BIN
resource/password_generator.exe
Normal file
BIN
resource/password_generator.exe
Normal file
Binary file not shown.
21
tools/viewer/IImageViewer.cs
Normal file
21
tools/viewer/IImageViewer.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
namespace KortAppZ.Tools.Viewer
|
||||||
|
{
|
||||||
|
public interface IImageViewer
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 加载图片文件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filePath">图片文件路径</param>
|
||||||
|
void LoadImage(string filePath);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 显示图片
|
||||||
|
/// </summary>
|
||||||
|
void ShowImage();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 关闭图片查看器
|
||||||
|
/// </summary>
|
||||||
|
void CloseViewer();
|
||||||
|
}
|
||||||
|
}
|
||||||
72
tools/viewer/ImageDisplayForm.cs
Normal file
72
tools/viewer/ImageDisplayForm.cs
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace KortAppZ.Tools.Viewer
|
||||||
|
{
|
||||||
|
public class ImageDisplayForm : Form
|
||||||
|
{
|
||||||
|
private PictureBox? pictureBox;
|
||||||
|
private Image? currentImage;
|
||||||
|
|
||||||
|
public ImageDisplayForm()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
this.pictureBox = new PictureBox();
|
||||||
|
//
|
||||||
|
// pictureBox
|
||||||
|
//
|
||||||
|
this.pictureBox.Dock = DockStyle.Fill;
|
||||||
|
this.pictureBox.SizeMode = PictureBoxSizeMode.Zoom;
|
||||||
|
this.pictureBox.BackColor = Color.Black;
|
||||||
|
//
|
||||||
|
// ImageDisplayForm
|
||||||
|
//
|
||||||
|
this.Text = "图片查看";
|
||||||
|
this.ClientSize = new Size(800, 600);
|
||||||
|
this.MaximizeBox = false;
|
||||||
|
this.MinimizeBox = true;
|
||||||
|
this.FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||||
|
this.ControlBox = true;
|
||||||
|
this.ShowIcon = true;
|
||||||
|
this.MaximizedBounds = Screen.FromHandle(this.Handle).WorkingArea;
|
||||||
|
this.Controls.Add(this.pictureBox);
|
||||||
|
this.FormClosing += new FormClosingEventHandler(ImageDisplayForm_FormClosing);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LoadImage(string filePath)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (currentImage != null)
|
||||||
|
{
|
||||||
|
currentImage.Dispose();
|
||||||
|
currentImage = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentImage = ImageFileHandler.LoadImage(filePath);
|
||||||
|
pictureBox.Image = currentImage;
|
||||||
|
this.Text = $"图片查看 - {Path.GetFileName(filePath)}";
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"无法加载图片: {ex.Message}", "错误",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ImageDisplayForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||||
|
{
|
||||||
|
if (currentImage != null)
|
||||||
|
{
|
||||||
|
currentImage.Dispose();
|
||||||
|
currentImage = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
41
tools/viewer/ImageFileHandler.cs
Normal file
41
tools/viewer/ImageFileHandler.cs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace KortAppZ.Tools.Viewer
|
||||||
|
{
|
||||||
|
public static class ImageFileHandler
|
||||||
|
{
|
||||||
|
private static readonly string[] SupportedExtensions =
|
||||||
|
{
|
||||||
|
".jpg", ".jpeg", ".png", ".bmp", ".gif", ".tiff", ".tif"
|
||||||
|
};
|
||||||
|
|
||||||
|
public static bool IsImageFile(string filePath)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(filePath))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
string extension = Path.GetExtension(filePath).ToLower();
|
||||||
|
return Array.Exists(SupportedExtensions, ext => ext == extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Image LoadImage(string filePath)
|
||||||
|
{
|
||||||
|
if (!IsImageFile(filePath))
|
||||||
|
throw new ArgumentException("不支持的图片格式");
|
||||||
|
|
||||||
|
if (!File.Exists(filePath))
|
||||||
|
throw new FileNotFoundException("图片文件不存在", filePath);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return Image.FromFile(filePath);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new Exception($"无法加载图片: {ex.Message}", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
93
tools/viewer/ImageViewerForm.cs
Normal file
93
tools/viewer/ImageViewerForm.cs
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using System.IO;
|
||||||
|
using KortAppZ.Tools.Viewer;
|
||||||
|
|
||||||
|
namespace KortAppZ.Tools.Viewer
|
||||||
|
{
|
||||||
|
public class ImageViewerForm : Form
|
||||||
|
{
|
||||||
|
private Button? openButton;
|
||||||
|
|
||||||
|
public ImageViewerForm()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
this.openButton = new Button();
|
||||||
|
//
|
||||||
|
// openButton
|
||||||
|
//
|
||||||
|
this.openButton.Text = "打开图片";
|
||||||
|
this.openButton.Size = new Size(120, 40);
|
||||||
|
this.openButton.Font = new Font("Microsoft YaHei", 10);
|
||||||
|
this.openButton.Anchor = AnchorStyles.None;
|
||||||
|
this.openButton.Click += new EventHandler(OpenButton_Click);
|
||||||
|
|
||||||
|
// 初始位置
|
||||||
|
CenterOpenButton();
|
||||||
|
|
||||||
|
// 窗体大小变化时重新居中按钮
|
||||||
|
this.Resize += (s, e) => CenterOpenButton();
|
||||||
|
|
||||||
|
//
|
||||||
|
// ImageViewerForm
|
||||||
|
//
|
||||||
|
this.Text = "图片查看器";
|
||||||
|
this.ClientSize = new Size(400, 300);
|
||||||
|
this.StartPosition = FormStartPosition.CenterScreen;
|
||||||
|
this.MinimumSize = new Size(300, 200);
|
||||||
|
this.MaximizeBox = false;
|
||||||
|
this.FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||||
|
this.MaximizedBounds = Screen.FromHandle(this.Handle).WorkingArea;
|
||||||
|
this.Controls.Add(this.openButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CenterOpenButton()
|
||||||
|
{
|
||||||
|
if (openButton != null)
|
||||||
|
{
|
||||||
|
openButton.Location = new Point(
|
||||||
|
(this.ClientSize.Width - openButton.Width) / 2,
|
||||||
|
(this.ClientSize.Height - openButton.Height) / 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
OpenFileDialog openFileDialog = new OpenFileDialog();
|
||||||
|
openFileDialog.Filter = "图片文件|*.jpg;*.jpeg;*.png;*.bmp;*.gif;*.tiff;*.tif|所有文件|*.*";
|
||||||
|
|
||||||
|
if (openFileDialog.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
string filePath = openFileDialog.FileName;
|
||||||
|
ShowImage(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShowImage(string filePath)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!ImageFileHandler.IsImageFile(filePath))
|
||||||
|
{
|
||||||
|
MessageBox.Show("不支持的图片格式", "错误",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageDisplayForm displayForm = new ImageDisplayForm();
|
||||||
|
displayForm.LoadImage(filePath);
|
||||||
|
displayForm.Show();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"无法加载图片: {ex.Message}", "错误",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
48
tools/viewer/ImageViewerToolCard.cs
Normal file
48
tools/viewer/ImageViewerToolCard.cs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using System.IO;
|
||||||
|
using AppStore;
|
||||||
|
|
||||||
|
namespace KortAppZ.Tools.Viewer
|
||||||
|
{
|
||||||
|
public class ImageViewerToolCard : ToolCard
|
||||||
|
{
|
||||||
|
public ImageViewerToolCard()
|
||||||
|
{
|
||||||
|
this.ToolName = "图片查看";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string iconPath = Path.Combine(Application.StartupPath, "img", "resource", "png", "ImageCompressor.png");
|
||||||
|
if (File.Exists(iconPath))
|
||||||
|
{
|
||||||
|
this.ToolIcon = Image.FromFile(iconPath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.ToolIcon = SystemIcons.Application.ToBitmap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
this.ToolIcon = SystemIcons.Application.ToBitmap();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.ToolCardClicked += (s, e) => {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ImageViewerForm viewerForm = new ImageViewerForm();
|
||||||
|
viewerForm.Show();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"打开图片查看器失败: {ex.Message}", "错误",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.UpdateDisplay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user