我想使用带有自定义记录的TFPGList。我花了很长时间才从互联网上获得所有必要的提示,以编制此小片段:
program Project1;
{$mode delphi}{$H+}
uses
fgl;
type
TSomeRecord = record
feld_1: Byte;
class operator Equal(Left, Right : TSomeRecord) Result : Boolean;
end;
class operator TSomeRecord.Equal (Left, Right: TSomeRecord) Result: Boolean;
begin
Result := Left.feld_1 = Right.feld_1;
end;
type
TypedList = TFPGList<TSomeRecord>;
var
x : TypedList;
begin
end.
如您所见,问题在于为记录指定Equal运算符。此外,这似乎仅在delphi模式下可行。
假定我不想以delphi模式而是以objfpc模式编写该程序:为记录指定Equal运算符的正确语法是什么?有可能吗?
我的fpc版本是3.0.4
答案 0 :(得分:2)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Demo {
public class FormVisibleFalse : Form {
private const int WM_SETFOCUS = 0x7;
private const int SW_RESTORE = 9;
private bool setVisible = true;
NotifyIcon notifyIcon = new NotifyIcon();
FormWindowState windowState = FormWindowState.Normal;
Button btnIsVisible = new Button { Text = "IsVisible", AutoSize = true, AutoSizeMode = AutoSizeMode.GrowAndShrink };
IntPtr mainWindowHandle = IntPtr.Zero;
public FormVisibleFalse() {
Text = "Form.Visible = False";
notifyIcon.MouseClick += notifyIcon_MouseClick;
notifyIcon.Icon = this.Icon;
btnIsVisible.Click += btnIsVisible_Click;
FlowLayoutPanel p = new FlowLayoutPanel { Dock = DockStyle.Fill, WrapContents = false, FlowDirection = FlowDirection.TopDown };
p.Controls.Add(btnIsVisible);
p.Controls.Add(new Label { Text = "After minimizing the form, click the IsVisible button.", AutoSize = true });
Controls.Add(p);
this.StartPosition = FormStartPosition.CenterScreen;
}
protected override void OnHandleCreated(EventArgs e) {
base.OnHandleCreated(e);
mainWindowHandle = this.Handle;
}
void btnIsVisible_Click(object sender, EventArgs e) {
MessageBox.Show("Form.Visible = " + this.Visible);
}
void notifyIcon_MouseClick(object sender, MouseEventArgs e) {
setVisible = false;
this.Visible = true;
this.WindowState = windowState;
notifyIcon.Visible = false;
}
protected override void OnSizeChanged(EventArgs e) {
base.OnSizeChanged(e);
if (this.WindowState == FormWindowState.Minimized) {
this.Visible = false;
notifyIcon.Visible = true;
setVisible = true;
// two seconds later, restore the form.
// Note: This is just a simple way to illustrate the problem. The actual pinvoke call
// is made from a second instance of the process that detects if an instance is
// already running, and restores the main window. A pipe listener could also be used to
// pass a message telling the running instance to restore, but that's a more complicated
// solution.
Thread t = new Thread(() => {
Thread.Sleep(2000);
ShowWindow(mainWindowHandle, SW_RESTORE); // also tried SW_NORMAL and SW_SHOW
SetForegroundWindow(mainWindowHandle);
});
t.IsBackground = true;
t.Start(); // after this runs, then click the IsVisible button
}
else {
windowState = this.WindowState;
}
}
protected override void WndProc(ref Message m) {
base.WndProc(ref m);
if (m.Msg == WM_SETFOCUS && setVisible) {
setVisible = false;
// this.Visible = true; // <-- this fixes the problem but is there a more correct way?
notifyIcon.Visible = false;
}
}
protected override void Dispose(bool disposing) {
base.Dispose(disposing);
if (disposing) {
notifyIcon.Dispose();
}
}
[DllImport("user32.dll")]
public static extern int ShowWindow(IntPtr hWnd, int cmdShow);
[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
}
}