新增托盘图标

This commit is contained in:
2026-03-01 10:42:42 +08:00
parent 0ba966cef2
commit e03e1b9766
26 changed files with 582 additions and 72 deletions

View File

@@ -1,5 +1,4 @@
using System.Collections;
using System.Diagnostics;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Windows.Media.Animation;

View File

@@ -235,7 +235,7 @@ namespace Melskin.Controls
}
view.Refresh();
// !string.IsNullOrEmpty(Text) 的判断
// !string.IsNullOrEmpty(Tip) 的判断
if (!string.IsNullOrEmpty(Text) && !view.IsEmpty && textBox is { IsKeyboardFocused: true })
{
IsDropDownOpen = true;

View File

@@ -17,7 +17,7 @@ namespace Melskin.Controls.Decorations;
/// CornerRadius="10"
/// Background="#40FF0000">
/// <!-- 半透明红色背景 -->
/// <TextBlock Text = "Mini Card" Foreground="White" FontSize="16"/>
/// <TextBlock Tip = "Mini Card" Foreground="White" FontSize="16"/>
///</GlassChromeDecorator>
/// </code>
/// <![CDATA[]]>

View File

@@ -1,5 +1,4 @@
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices;
using System.Windows.Input;
namespace Melskin.Controls;
@@ -193,7 +192,7 @@ public class MelWindow : Window
if (maximizeRestoreButton is Visual maximizeButtonVisual)
{
var bounds = VisualTreeHelper.GetDescendantBounds(maximizeButtonVisual);
Debug.WriteLine(bounds.ToString());
//Debug.WriteLine(bounds.ToString());
var buttonTransform = maximizeButtonVisual.TransformToAncestor(this);
var buttonRect = buttonTransform.TransformBounds(bounds);

View File

@@ -83,7 +83,7 @@ public partial class ToastControl
// foreground = new SolidColorBrush(Color.FromRgb(245, 108, 108));
// break;
// }
// control.IconTextBlock.Text = icon;
// control.IconTextBlock.Tip = icon;
// control.IconTextBlock.Foreground = foreground;
// control.RootBorder.Background = background;
// control.RootBorder.BorderBrush = background;

View File

@@ -0,0 +1,216 @@
using System.Runtime.InteropServices;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
namespace Melskin.Controls
{
public class TrayIcon : FrameworkElement, IDisposable
{
// 1. 悬浮提示文本
public static readonly DependencyProperty TipProperty =
DependencyProperty.Register(nameof(Tip), typeof(string), typeof(TrayIcon),
new PropertyMetadata(string.Empty, OnTextChanged));
public string Tip
{
get => (string)GetValue(TipProperty);
set => SetValue(TipProperty, value);
}
// 2. 双击命令
public static readonly DependencyProperty DoubleClickCommandProperty =
DependencyProperty.Register(nameof(DoubleClickCommand), typeof(ICommand), typeof(TrayIcon));
public ICommand DoubleClickCommand
{
get => (ICommand)GetValue(DoubleClickCommandProperty);
set => SetValue(DoubleClickCommandProperty, value);
}
public static readonly DependencyProperty ClickCommandProperty =
DependencyProperty.Register(nameof(ClickCommand), typeof(ICommand), typeof(TrayIcon));
public ICommand ClickCommand
{
get => (ICommand)GetValue(ClickCommandProperty);
set => SetValue(ClickCommandProperty, value);
}
// 3. 【新增】图标本地路径 (例如: "app.ico")
public static readonly DependencyProperty IconPathProperty =
DependencyProperty.Register(nameof(IconPath), typeof(string), typeof(TrayIcon),
new PropertyMetadata(string.Empty, OnIconPathChanged));
public string IconPath
{
get => (string)GetValue(IconPathProperty);
set => SetValue(IconPathProperty, value);
}
private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctrl = (TrayIcon)d;
if (ctrl._isAdded)
{
ctrl._nid.szTip = e.NewValue?.ToString() ?? "";
Shell_NotifyIcon(NIM_MODIFY, ref ctrl._nid);
}
}
private static void OnIconPathChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctrl = (TrayIcon)d;
if (ctrl._isAdded)
{
ctrl._nid.hIcon = ctrl.LoadMyIcon(e.NewValue?.ToString());
Shell_NotifyIcon(NIM_MODIFY, ref ctrl._nid);
}
}
// --- Win32 API 声明 ---
private const int NIM_ADD = 0x0000;
private const int NIM_MODIFY = 0x0001;
private const int NIM_DELETE = 0x0002;
private const int NIF_MESSAGE = 0x0001;
private const int NIF_ICON = 0x0002;
private const int NIF_TIP = 0x0004;
private const int WM_LBUTTONUP = 0x0202; // 左键弹起消息
private const int WM_TRAYMOUSEMESSAGE = 0x0400 + 1024;
private const int WM_LBUTTONDBLCLK = 0x0203;
private const int WM_RBUTTONUP = 0x0205; [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct NOTIFYICONDATA
{
public int cbSize;
public IntPtr hwnd;
public int uID;
public int uFlags;
public int uCallbackMessage;
public IntPtr hIcon; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string szTip;
public int dwState;
public int dwStateMask; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string szInfo;
public int uTimeoutOrVersion;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string szInfoTitle;
public int dwInfoFlags;
public Guid guidItem;
public IntPtr hBalloonIcon;
}
[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
private static extern bool Shell_NotifyIcon(int dwMessage, ref NOTIFYICONDATA pnid);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetForegroundWindow(IntPtr hWnd);
// 【新增】纯 Win32 加载本地图标 API
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
private static extern IntPtr LoadImage(IntPtr hInst, string lpszName, uint uType, int cxDesired, int cyDesired, uint fuLoad);
private IntPtr LoadMyIcon(string iconPath)
{
if (string.IsNullOrEmpty(iconPath)) return IntPtr.Zero;
// 1 = IMAGE_ICON, 0x00000010 = LR_LOADFROMFILE
return LoadImage(IntPtr.Zero, iconPath, 1, 0, 0, 0x00000010);
}
// --- 内部状态 ---
private HwndSource _messageSink;
private int _uID = 100;
private bool _isAdded = false;
private NOTIFYICONDATA _nid;
public TrayIcon()
{
Visibility = Visibility.Collapsed;
this.Loaded += OnLoaded;
this.Unloaded += OnUnloaded;
if (Application.Current != null)
Application.Current.Exit += (s, e) => Dispose();
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
if (_isAdded) return;
HwndSourceParameters p = new HwndSourceParameters("TrayIconMessageSink")
{
Width = 0, Height = 0, WindowStyle = 0, ExtendedWindowStyle = 0x00000080
};
_messageSink = new HwndSource(p);
_messageSink.AddHook(WndProc);
_nid = new NOTIFYICONDATA
{
cbSize = Marshal.SizeOf(typeof(NOTIFYICONDATA)),
hwnd = _messageSink.Handle,
uID = _uID,
uFlags = NIF_MESSAGE | NIF_TIP | NIF_ICON,
uCallbackMessage = WM_TRAYMOUSEMESSAGE,
szTip = this.Tip ?? "",
// 加载属性中指定的图标
hIcon = LoadMyIcon(this.IconPath)
};
Shell_NotifyIcon(NIM_ADD, ref _nid);
_isAdded = true;
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == WM_TRAYMOUSEMESSAGE)
{
int mouseMsg = lParam.ToInt32();
if (mouseMsg == WM_LBUTTONUP)
{
if (ClickCommand?.CanExecute(null) == true)
{
ClickCommand.Execute(null);
}
handled = true;
}
else if (mouseMsg == WM_LBUTTONDBLCLK)
{
if (DoubleClickCommand?.CanExecute(null) == true)
DoubleClickCommand.Execute(null);
handled = true;
}
else if (mouseMsg == WM_RBUTTONUP)
{
ShowContextMenu();
handled = true;
}
}
return IntPtr.Zero;
}
private void ShowContextMenu()
{
if (this.ContextMenu != null)
{
SetForegroundWindow(_messageSink.Handle);
this.ContextMenu.PlacementTarget = null;
this.ContextMenu.Placement = PlacementMode.MousePoint;
this.ContextMenu.IsOpen = true;
}
}
private void OnUnloaded(object sender, RoutedEventArgs e) => Dispose();
public void Dispose()
{
if (_isAdded)
{
Shell_NotifyIcon(NIM_DELETE, ref _nid);
_isAdded = false;
}
if (_messageSink != null)
{
_messageSink.RemoveHook(WndProc);
_messageSink.Dispose();
_messageSink = null;
}
}
}
}

View File

@@ -14,7 +14,7 @@ namespace Melskin.Markup;
/// 使用此扩展时需要确保已正确引用了Material Design图标字体资源。可以通过设置`FontFamily`属性来应用图标字体。
/// </remarks>
/// <example>
/// <code lang="xml"> &lt;TextBlock Text="{enu:SymbolIcon Symbol=AddBox}" FontFamily="{StaticResource MaterialIconFont}"/&gt;
/// <code lang="xml"> &lt;TextBlock Tip="{enu:SymbolIcon Symbol=AddBox}" FontFamily="{StaticResource MaterialIconFont}"/&gt;
/// </code>
/// </example>
[ContentProperty(nameof(Symbol))]

View File

@@ -120,6 +120,27 @@
<RowDefinition Height="*" />
<RowDefinition Height="24" />
</Grid.RowDefinitions>
<ms:TrayIcon
x:Name="MyTray"
ClickCommand="{Binding ShowWindowCommand}"
DoubleClickCommand="{Binding ShowWindowCommand}"
IconPath="Resources/Images/authentication.ico"
Tip="我的WPF程序托盘">
<!-- 原生的 WPF 右键菜单 -->
<ms:TrayIcon.ContextMenu>
<ContextMenu>
<!-- 支持普通的 Click 事件 -->
<MenuItem
Click="MenuShow_Click"
FontWeight="Bold"
Header="显示主界面" />
<Separator />
<MenuItem Click="MenuExit_Click" Header="完全退出" />
</ContextMenu>
</ms:TrayIcon.ContextMenu>
</ms:TrayIcon>
<!-- 工具栏 -->
<ToolBarTray Margin="4,4,4,0">
<ToolBar Foreground="{DynamicResource PrimaryFocusedBrush}" Header="工具栏">

View File

@@ -1,11 +1,9 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
@@ -82,6 +80,7 @@ public partial class MainWindow
#region
public ICommand ShowSelectedItemsCommand { get; set; }
public ICommand ToggleDetailsCommand { get; set; }
public ICommand ShowWindowCommand { get; set; }
[RelayCommand]
private void AddArea()
@@ -227,6 +226,7 @@ public partial class MainWindow
{
ShowSelectedItemsCommand = new RelayCommand(ShowSelectedItems);
ToggleDetailsCommand = new RelayCommand<PersonItem>(ToggleDetails);
ShowWindowCommand = new RelayCommand(ShowWindow);
}
#endregion
@@ -462,6 +462,32 @@ public partial class MainWindow
break;
}
}
private void ShowWindow()
{
this.Show();
this.WindowState = WindowState.Normal;
this.Activate(); // 激活窗口使其置顶
}
// --- 2. 右键菜单的 Click 事件 (Code-behind 风格) ---
private void MenuShow_Click(object sender, RoutedEventArgs e)
{
ShowWindow();
}
private void MenuExit_Click(object sender, RoutedEventArgs e)
{
// 真正退出程序
Application.Current.Shutdown();
}
// --- 3. 重写关闭事件实现“点X最小化到托盘” ---
protected override void OnClosing(CancelEventArgs e)
{
// 阻止窗口真正销毁
e.Cancel = true;
// 隐藏窗口(此时托盘图标依然在运行)
this.Hide();
}
}
#region

View File

@@ -34,5 +34,10 @@
<ItemGroup>
<Reference Include="System.Management" />
</ItemGroup>
<ItemGroup>
<None Update="Resources\Images\authentication.ico">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -1,12 +1,12 @@
using Autodesk.Revit.Attributes;
using Nice3point.Revit.Toolkit.External;
using ShrlAlgoToolkit.RevitAddins.Common.Assists;
namespace ShrlAlgoToolkit.RevitAddins.ModelManager;
[Transaction(TransactionMode.Manual)]
[UsedImplicitly]
public class ModelCheckCmd : ExternalCommand
{
public override void Execute() => WinDialogAssist.ShowOrActivate<ModelCheckView, ModelCheckViewModel>(UiApplication);//ModelCheckView view = SingletonViewAssist<ModelCheckView>.GetInstance(out var isNewCreate);//if (isNewCreate)//{// view.DataContext = new ModelCheckViewModel(uiApplication);// view.ShowAhead();//}//view.Activate();

View File

@@ -23,7 +23,6 @@ using ShrlAlgoToolkit.RevitAddins.Common.Controls;
namespace ShrlAlgoToolkit.RevitAddins.ModelManager;
[UsedImplicitly]
public partial class ModelCheckViewModel : ObservableObject
{
private readonly Standardizer.CorrectReferLevelExecutes correctReferLevelExecutes;

View File

@@ -3,48 +3,7 @@ using System.Text.RegularExpressions;
namespace ShrlAlgoToolkit.RevitAddins.Common.Extensions;
#region
//StringFormat={}{0:C} $123.46
//StringFormat={}{0:C1} $123.5
//StringFormat=单价:{0:C} 单价:$123.46
//StringFormat={}{0}元 123.45678元
//StringFormat={}{0:D6} 086723
//StringFormat={}{0:F4} 28768234.9329
//StringFormat={}{0:N3} 28,768,234.933
//StringFormat={}{0:P1} 78.9 %
//StringFormat={}{0:0000.00} 0123.46
//StringFormat={}{0:####.##} 123.46
//StringFormat={}{0:d} 5/4/2015
//StringFormat={}{0:D} Monday, May 04, 2015
//StringFormat={}{0:f} Monday, May 04, 2015 5:46 PM
//StringFormat={}{0:F} Monday, May 04, 2015 5:46:56 PM
//StringFormat={}{0:g} 5/4/2015 5:46 PM
//StringFormat={}{0:G} 5/4/2015 5:46:56 PM
//StringFormat={}{0:m} May 04
//StringFormat={}{0:Distinct} May 04
//StringFormat={}{0:t} 5:46 PM
//StringFormat={}{0:Command} 5:46:56 PM
//StringFormat={}{0:yyyy年MM月dd日} 2015年05月04日
//StringFormat={}{0:yyyy-MM-dd} 2015-05-04
//StringFormat={}{0:yyyy-MM-dd HH:mm} 2015-05-04 17:46
//StringFormat={}{0:yyyy-MM-dd HH:mm:ss},,ConverterCulture=zh-CN||StringFormat='yyyy:MM:dd HH:mm:ss',,ConverterCulture=zh-CN 2015-05-04 17:46:56
//< TextBox.Text >
// < MultiBinding StringFormat = "姓名:{0}&#x09;{1}" >
// < Binding Path = "FristName" />
// < Binding Path = "LastName" />
// </ MultiBinding >
//</ TextBox.Text >
// < !--
// \a &#x07; BEL
// \b &#x08; BS - Backspace
// \f &#x0c; FF - Formfeed
// \n &#x0a; LF, NL - Linefeed, New Line
// \r &#x0d; CR - Carriage return
// \t &#x09; HT - Tab, Horizontal Tabelator
// \v &#x0b; VT - Vertical Tabelator
#endregion
public static class StringExtensions
{
/// <summary>

View File

@@ -13,7 +13,7 @@ public class RequiredValidationRule : ValidationRule
// InputMethod.IsInputMethodEnabled= "False"
// md:HintAssist.Hint= "楼板偏移"
// md:TextFieldAssist.SuffixText= "mm" >
// < TextBox.Text >
// < TextBox.Tip >
// < Binding
// Path= "FloorOffset"
// StringFormat= "{}{0:N2}"
@@ -23,7 +23,7 @@ public class RequiredValidationRule : ValidationRule
// <domain:RangeValidationRule Max = "100" Min= "0" xmlns:domain= "clr-namespace:Sai.Toolkit.Mvvm.ValidationRules" ValidatesOnTargetUpdated = "True" />
// </ Binding.ValidationRules >
// </ Binding >
// </ TextBox.Text >
// </ TextBox.Tip >
// </ TextBox >
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{

View File

@@ -129,7 +129,7 @@ public class DrawingViewApp
// LargeImage = Resources.zoom_32px.ToBitmapSource(),
// Size = RibbonItemSize.Large,
// Name = "ZoomElement",
// Text = "最大化",
// Tip = "最大化",
// ShowText = true,
// ToolTip = "根据视图的图元是否可见,在切换视图时,对当前选中的图元进行快速缩放定位",
// IsCheckable = true,

View File

@@ -359,7 +359,7 @@ public partial class FamilyLibraryViewModel : ObservableObject
private void SearchFamily(object obj)
{
//ListViewItem foundItem =
// textListView.FindItemWithText(searchBox.Text, false, 0, true);
// textListView.FindItemWithText(searchBox.Tip, false, 0, true);
//if (foundItem != null)
//{
// textListView.TopItem = foundItem;

View File

@@ -0,0 +1,52 @@
using System.IO;
using System.Reflection;
using Autodesk.Revit.DB;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
namespace Szmedi.RvKits.LLMScript
{
public class CodeExecutor
{
public void Execute(string methodBody, Autodesk.Revit.DB.Document doc, UIDocument uidoc)
{
string code = $@"
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using System;
public class ScriptRunner
{{
public void Run(Document doc, UIDocument uidoc)
{{
{methodBody}
}}
}}";
var syntaxTree = CSharpSyntaxTree.ParseText(code);
var compilation = CSharpCompilation.Create(
"DynamicScript")
.AddReferences(
MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
MetadataReference.CreateFromFile(typeof(Document).Assembly.Location))
.AddSyntaxTrees(syntaxTree)
.WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
using var ms = new MemoryStream();
var result = compilation.Emit(ms);
if (!result.Success)
throw new Exception("Compilation failed");
ms.Seek(0, SeekOrigin.Begin);
var assembly = Assembly.Load(ms.ToArray());
var type = assembly.GetType("ScriptRunner");
var instance = Activator.CreateInstance(type);
type.GetMethod("Run").Invoke(instance, new object[] { doc, uidoc });
}
}
}

View File

@@ -0,0 +1,11 @@
using System.Threading.Tasks;
namespace Szmedi.RvKits.LLMScript
{
internal interface ILLMProvider
{
Task GenerateStreamAsync(string systemPrompt,
string userPrompt,
Action<string> onTokenReceived);
}
}

View File

@@ -0,0 +1,40 @@
using System.Text;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Nice3point.Revit.Toolkit.External;
namespace Szmedi.RvKits.LLMScript
{
/// <summary>
/// Revit执行命令
/// </summary>
[Transaction(TransactionMode.Manual)]
[Regeneration(RegenerationOption.Manual)]
public class LLMCmd : ExternalCommand
{
public async override void Execute()
{
string userTask = "将当前选中墙的Comments参数追加'检查'";
PromptManager promptManager = new PromptManager("Prompts/System_UltraStrict.txt");
string systemPrompt = promptManager.GetSystemPrompt();
string userPrompt = promptManager.BuildUserPrompt(userTask);
var llm = new OllamaProvider("http://localhost:11434/api/chat", "revit-coder");
StringBuilder fullCode = new StringBuilder();
await llm.GenerateStreamAsync(
systemPrompt,
userPrompt,
chunk =>
{
fullCode.Append(chunk);
});
CodeExecutor executor = new CodeExecutor();
executor.Execute(fullCode.ToString(), Document, UiDocument);
}
}
}

View File

@@ -0,0 +1,74 @@
using System.IO;
using System.Net.Http;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Szmedi.RvKits.LLMScript
{
public class OllamaProvider : ILLMProvider
{
private static readonly HttpClient _client = new HttpClient();
private readonly string _endpoint;
private readonly string _model;
public OllamaProvider(string endpoint, string model)
{
_endpoint = endpoint;
_model = model;
}
public async Task GenerateStreamAsync(
string systemPrompt,
string userPrompt,
Action<string> onTokenReceived)
{
var payload = new
{
model = _model,
messages = new[]
{
new { role = "system", content = systemPrompt },
new { role = "user", content = userPrompt }
},
stream = true
};
string json = JsonConvert.SerializeObject(payload);
var request = new HttpRequestMessage(HttpMethod.Post, _endpoint);
request.Content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await _client.SendAsync(
request,
HttpCompletionOption.ResponseHeadersRead);
response.EnsureSuccessStatusCode();
using (var stream = await response.Content.ReadAsStreamAsync())
using (var reader = new StreamReader(stream))
{
while (!reader.EndOfStream)
{
string line = await reader.ReadLineAsync();
if (string.IsNullOrWhiteSpace(line))
continue;
JObject obj = JObject.Parse(line);
bool done = obj["done"]?.Value<bool>() ?? false;
var content = obj["message"]?["content"];
if (content != null)
{
onTokenReceived(content.ToString());
}
if (done)
break;
}
}
}
}
}

View File

@@ -0,0 +1,84 @@
using System.IO;
using System.Net.Http;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Szmedi.RvKits.LLMScript
{
public class OpenAiProvider : ILLMProvider
{
private static readonly HttpClient _client = new HttpClient();
private readonly string _endpoint;
private readonly string _apiKey;
private readonly string _model;
public OpenAiProvider(string endpoint, string apiKey, string model)
{
_endpoint = endpoint;
_apiKey = apiKey;
_model = model;
_client.DefaultRequestHeaders.Clear();
_client.DefaultRequestHeaders.Add("Authorization", $"Bearer {_apiKey}");
}
public async Task GenerateStreamAsync(
string systemPrompt,
string userPrompt,
Action<string> onTokenReceived)
{
var payload = new
{
model = _model,
messages = new[]
{
new { role = "system", content = systemPrompt },
new { role = "user", content = userPrompt }
},
temperature = 0,
stream = true
};
string json = JsonConvert.SerializeObject(payload);
var request = new HttpRequestMessage(HttpMethod.Post, _endpoint);
request.Content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await _client.SendAsync(
request,
HttpCompletionOption.ResponseHeadersRead);
response.EnsureSuccessStatusCode();
using (var stream = await response.Content.ReadAsStreamAsync())
using (var reader = new StreamReader(stream))
{
while (!reader.EndOfStream)
{
string line = await reader.ReadLineAsync();
if (string.IsNullOrWhiteSpace(line))
continue;
if (!line.StartsWith("data:"))
continue;
string data = line.Substring(5).Trim();
if (data == "[DONE]")
break;
JObject obj = JObject.Parse(data);
var delta = obj["choices"]?[0]?["delta"]?["content"];
if (delta != null)
{
onTokenReceived(delta.ToString());
}
}
}
}
}
}

View File

@@ -0,0 +1,24 @@
using System.IO;
namespace Szmedi.RvKits.LLMScript
{
public class PromptManager
{
private readonly string _systemPrompt;
public PromptManager(string promptPath)
{
_systemPrompt = File.ReadAllText(promptPath);
}
public string GetSystemPrompt()
{
return _systemPrompt;
}
public string BuildUserPrompt(string task)
{
return task.Trim();
}
}
}

View File

@@ -1,4 +1,4 @@
global using Autodesk.Revit.UI;
global using JetBrains.Annotations;
global using ShrlAlgoToolkit.RevitCore.Assists;
global using ShrlAlgoToolkit.RevitCore.Extensions;

View File

@@ -86,6 +86,9 @@
<!-- <Reference Include="Microsoft.CSharp" Condition="'$(RevitVersion)' == '2018' Or '$(RevitVersion)' == '2019' Or '$(RevitVersion)' == '2020'" />
<Reference Include="System.ComponentModel.DataAnnotations" Condition="'$(RevitVersion)' == '2018' Or '$(RevitVersion)' == '2019' Or '$(RevitVersion)' == '2020' " />-->
<Reference Include="eTransmitForRevitDB" HintPath="..\libs\$(RevitVersion)\eTransmitForRevitDB.dll" />
<Reference Include="System.Net.Http">
<HintPath>C:\Program Files\Microsoft Visual Studio\18\Community\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Net.Http.dll</HintPath>
</Reference>
<!-- <Reference Include="RevitAPIIFC" Condition=" '$(RevitVersion)' == '2025' " HintPath="..\libs\$(RevitVersion)\RevitAPIIFC.dll" Private="False" />
<Reference Include="UIFramework" HintPath="..\libs\$(RevitVersion)\UIFramework.dll" Private="False" />
<Reference Include="UIFrameworkServices" HintPath="..\libs\$(RevitVersion)\UIFrameworkServices.dll" Private="False" />-->
@@ -101,9 +104,11 @@
<PackageReference Include="ACadSharp" Version="3.4.9" />
<PackageReference Include="FuzzySharp" Version="2.0.2" />
<PackageReference Include="HtmlAgilityPack" Version="1.12.4" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="5.0.0" />
<!--TreatAsUsed="true"标记为已使用-->
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.135" TreatAsUsed="True" />
<PackageReference Include="Nice3point.Revit.Extensions" Version="2020.3.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<!--<PackageReference Include="Nice3point.Revit.Extensions" Version="2020.3.0" />-->
<PackageReference Include="Nice3point.Revit.Toolkit" Version="2020.*" />
<PackageReference Include="MiniExcel" Version="1.42.0" />

View File

@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB;
namespace ShrlAlgoToolkit.RevitCore.Base
{