Skip to content

Commit 6de32d0

Browse files
committed
调整主界面
1 parent 596bf55 commit 6de32d0

17 files changed

Lines changed: 367 additions & 257 deletions

StartPro/Api/PEIcon.cs

Lines changed: 78 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -10,110 +10,127 @@ namespace StartPro.Api;
1010

1111
public static class PEIcon
1212
{
13-
public static bool FromFile(string fileName, out BitmapSource source)
13+
public static bool Complex(string path, out BitmapSource source)
1414
{
15-
if (string.IsNullOrEmpty(fileName))
15+
if (string.IsNullOrEmpty(path))
1616
{
1717
source = null;
1818
return false;
1919
}
20-
Icon icon = GetDirect(fileName);
21-
return FromIcon(icon, out source);
20+
IntPtr imgPtr = ComplexBitmap(path);
21+
return FromBitmap(imgPtr, out source);
2222
}
2323

24-
public static bool FromIcon(Icon icon, out BitmapSource source)
24+
public static IntPtr ComplexBitmap(string path)
2525
{
26-
source = null;
27-
if (icon is null)
28-
return false;
29-
IntPtr handle = icon.Handle;
30-
if (handle == IntPtr.Zero)
31-
return false;
26+
if (string.IsNullOrEmpty(path))
27+
return IntPtr.Zero;
28+
29+
IntPtr pImgFactory = IntPtr.Zero;
3230
try
3331
{
34-
source = Imaging.CreateBitmapSourceFromHIcon(handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions( ));
35-
if (source is null)
36-
{
37-
return false;
38-
}
39-
else if (source.CanFreeze)
32+
Guid iid = IID_IShellItemImageFactory;
33+
SHCreateItemFromParsingName(path, IntPtr.Zero, ref iid, out pImgFactory);
34+
if (pImgFactory == IntPtr.Zero
35+
|| Marshal.GetObjectForIUnknown(pImgFactory) is not IShellItemImageFactory factory)
4036
{
41-
source.Freeze( );
37+
return IntPtr.Zero;
4238
}
43-
return true;
39+
40+
Marshal.Release(pImgFactory);
41+
pImgFactory = IntPtr.Zero;
42+
43+
SIZE size = new(256, 256);
44+
IntPtr hBitmap = IntPtr.Zero;
45+
factory.GetImage(size, SIIGBF.RESIZETOFIT | SIIGBF.BIGGERSIZEOK, out hBitmap);
46+
return hBitmap;
47+
4448
}
4549
catch { }
4650
finally
4751
{
48-
icon.Dispose( );
52+
if (pImgFactory != IntPtr.Zero)
53+
Marshal.Release(pImgFactory);
4954
}
50-
return false;
55+
return IntPtr.Zero;
56+
}
57+
58+
public static bool Direct(string path, out BitmapSource source)
59+
{
60+
if (string.IsNullOrEmpty(path))
61+
{
62+
source = null;
63+
return false;
64+
}
65+
Icon icon = DirectIcon(path);
66+
return FromIcon(icon, out source);
5167
}
5268

53-
public static Icon GetDirect(string fileName)
69+
public static Icon DirectIcon(string path)
5470
{
5571
try
5672
{
57-
return Icon.ExtractIcon(fileName, 0, 256);
73+
return path.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase)
74+
? Icon.ExtractIcon(path, 0, 256) : null;
5875
}
5976
catch
6077
{
6178
return null;
6279
}
6380
}
6481

65-
public static bool GetComplex(string path, out BitmapSource source)
82+
public static bool FromBitmap(IntPtr bitmap, out BitmapSource source)
6683
{
6784
source = null;
68-
69-
if (string.IsNullOrEmpty(path))
85+
if (bitmap == IntPtr.Zero)
7086
return false;
71-
72-
IntPtr pImgFactory = IntPtr.Zero;
7387
try
7488
{
75-
Guid iid = IID_IShellItemImageFactory;
76-
SHCreateItemFromParsingName(path, IntPtr.Zero, ref iid, out pImgFactory);
77-
if (pImgFactory == IntPtr.Zero)
78-
return false;
89+
source = Imaging.CreateBitmapSourceFromHBitmap(
90+
bitmap,
91+
IntPtr.Zero,
92+
Int32Rect.Empty,
93+
BitmapSizeOptions.FromEmptyOptions( ));
7994

80-
if (Marshal.GetObjectForIUnknown(pImgFactory) is not IShellItemImageFactory factory)
95+
if (source is null)
8196
return false;
97+
else if (source.CanFreeze)
98+
source.Freeze( );
99+
return true;
100+
}
101+
catch { }
102+
finally
103+
{
104+
DeleteObject(bitmap);
105+
}
106+
return false;
107+
}
82108

83-
Marshal.Release(pImgFactory);
84-
pImgFactory = IntPtr.Zero;
85-
86-
SIZE size = new(256, 256);
87-
IntPtr hBitmap = IntPtr.Zero;
88-
factory.GetImage(size, SIIGBF.RESIZETOFIT | SIIGBF.BIGGERSIZEOK, out hBitmap);
109+
public static bool FromIcon(Icon icon, out BitmapSource source)
110+
{
111+
source = null;
112+
if (icon is null)
113+
return false;
114+
IntPtr handle = icon.Handle;
115+
if (handle == IntPtr.Zero)
116+
return false;
117+
try
118+
{
119+
source = Imaging.CreateBitmapSourceFromHIcon(
120+
handle,
121+
Int32Rect.Empty,
122+
BitmapSizeOptions.FromEmptyOptions( ));
89123

90-
if (hBitmap == IntPtr.Zero)
124+
if (source is null)
91125
return false;
92-
93-
try
94-
{
95-
BitmapSource bs = Imaging.CreateBitmapSourceFromHBitmap(
96-
hBitmap,
97-
IntPtr.Zero,
98-
Int32Rect.Empty,
99-
BitmapSizeOptions.FromEmptyOptions( ));
100-
101-
if (bs.CanFreeze) bs.Freeze( );
102-
103-
source = bs;
104-
return true;
105-
}
106-
catch { }
107-
finally
108-
{
109-
DeleteObject(hBitmap);
110-
}
126+
else if (source.CanFreeze)
127+
source.Freeze( );
128+
return true;
111129
}
112130
catch { }
113131
finally
114132
{
115-
if (pImgFactory != IntPtr.Zero)
116-
Marshal.Release(pImgFactory);
133+
icon.Dispose( );
117134
}
118135
return false;
119136
}

StartPro/Api/SystemStart.cs

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@
1212

1313
namespace StartPro.Api;
1414

15-
#if WINDOWS
16-
15+
#if WINDOWS7_0_OR_GREATER
1716
public static partial class SystemTiles
1817
{
1918
private static readonly Dictionary<string, TileSize> SizeMap = new( )
@@ -24,7 +23,7 @@ public static partial class SystemTiles
2423
["4x4"] = TileSize.Large
2524
};
2625

27-
public static TileBase CreateTile(TileData data)
26+
public static TileBase CreateTile(TileRaw data)
2827
{
2928
return new AppTile
3029
{
@@ -42,11 +41,11 @@ public static TileBase CreateTile(TileData data)
4241
};
4342
}
4443

45-
public static List<TileData> ImportData( )
44+
public static List<TileRaw> ImportData( )
4645
{
4746
if (!GetXml(out XDocument xml))
4847
return [];
49-
List<TileData> result = [];
48+
List<TileRaw> result = [];
5049

5150
IEnumerable<XElement> groups = xml
5251
.Descendants( )
@@ -73,7 +72,7 @@ public static List<TileData> ImportData( )
7372
int row = int.TryParse(rowRaw, out int _row) ? _row : 0;
7473
if (row > rowMax) rowMax = row;
7574

76-
TileData tileData = ParseTileData(tile, row + rowAdjust, col + colAdjust);
75+
TileRaw tileData = ParseTileData(tile, row + rowAdjust, col + colAdjust);
7776
result.Add(tileData);
7877
}
7978
colAdjust += groupWidth + 1;
@@ -154,7 +153,7 @@ private static bool GetXml(out XDocument xml)
154153
}
155154
}
156155

157-
public record TileData(
156+
public record TileRaw(
158157
string AppName,
159158
string AppPath,
160159
string Arguments,
@@ -164,7 +163,7 @@ public record TileData(
164163
int Column
165164
);
166165

167-
private static TileData ParseTileData(XElement tile, int row, int col)
166+
private static TileRaw ParseTileData(XElement tile, int row, int col)
168167
{
169168
TileSize size = SizeMap[tile.Attribute("Size")!.Value];
170169
string name, path, arguments, icon;
@@ -189,17 +188,19 @@ private static TileData ParseTileData(XElement tile, int row, int col)
189188
icon = string.IsNullOrEmpty(arguments) ? path : lnk;
190189
}
191190
}
192-
return new TileData(name, path, arguments, icon, size, row, col);
191+
return new TileRaw(name, path, arguments, icon, size, row, col);
193192
}
194193
}
194+
#endif
195195

196+
#if WINDOWS
196197
public class SystemApp
197198
{
198199
public static ReadOnlyCollection<SystemApp> Apps;
199200
public static string SystemAppsPath = Environment.ExpandEnvironmentVariables("%ProgramData%\\Microsoft\\Windows\\Start Menu\\Programs");
200201
public static string UserAppsPath = Environment.ExpandEnvironmentVariables("%AppData%\\Microsoft\\Windows\\Start Menu\\Programs");
201202

202-
private Icon appIcon;
203+
private IntPtr appIcon;
203204
public BitmapSource AppIcon { get; set; }
204205

205206
public string AppName { get; set; }
@@ -210,37 +211,43 @@ public class SystemApp
210211

211212
public static void LoadApps( )
212213
{
213-
Apps = new ReadOnlyCollection<SystemApp>(
214-
[.. Directory.GetFiles(UserAppsPath, "*.lnk", SearchOption.AllDirectories)
215-
.Concat(Directory.GetFiles(SystemAppsPath, "*.lnk", SearchOption.AllDirectories))
216-
.Select(FromLazy).Where(static item => item is not null)]
217-
);
214+
string[] UserApps = Directory.GetFiles(UserAppsPath, "*.lnk", SearchOption.AllDirectories);
215+
string[] SystemApps = Directory.GetFiles(SystemAppsPath, "*.lnk", SearchOption.AllDirectories);
216+
Apps = new([.. UserApps.Concat(SystemApps).Select(FromLazy)]);
218217
}
219218

220219
public static void LoadIcon( )
221220
{
222221
foreach (SystemApp app in Apps)
223222
{
224-
app.AppIcon =
225-
PEIcon.FromIcon(app.appIcon, out BitmapSource source)
226-
? source : new BitmapImage( );
223+
app.AppIcon = PEIcon.FromIcon(Icon.FromHandle(app.appIcon), out BitmapSource source)
224+
? source
225+
: PEIcon.FromBitmap(app.appIcon, out BitmapSource source1)
226+
? source1
227+
: new BitmapImage( );
227228
app.AppIcon.Freeze( );
228229
}
229230
}
230231

231232
private static SystemApp FromLazy(string appPath)
232233
{
233234
string appName = Path.GetFileNameWithoutExtension(appPath);
234-
return !Integration.ResolveShortcut(appPath, out string target, out string arguments)
235-
? null
236-
: new SystemApp
235+
return appPath.EndsWith("*.lnk", StringComparison.InvariantCultureIgnoreCase)
236+
&& Integration.ResolveShortcut(appPath, out string target, out string arguments)
237+
? new SystemApp
237238
{
238239
AppName = appName,
239240
AppPath = target,
240241
Arguments = arguments,
241-
appIcon = PEIcon.GetDirect(target),
242+
appIcon = PEIcon.DirectIcon(target)?.Handle ?? IntPtr.Zero,
243+
}
244+
: new SystemApp
245+
{
246+
AppName = appName,
247+
AppPath = appPath,
248+
Arguments = string.Empty,
249+
appIcon = PEIcon.ComplexBitmap(appPath)
242250
};
243251
}
244252
}
245-
246253
#endif

0 commit comments

Comments
 (0)