我想知道是否可能,如果可以,如何将表单边框样式更改为Windows Basic而不是Aero主题?显然,首先考虑Aero是否启用,如果不启用,则无需尝试更改边框样式.
所以代替:

我们会:(模拟图像)

MDI应用程序已经为子表单执行此操作,但我不想要或不需要MDI应用程序.我试着查看Vcl.Forms的来源,看看我是否能找到任何相关的东西,但我无法 - 我可能是错的但我实际上认为绘制MDI表单的方式是由Windows而不是Delphi决定的.
DSiWin32包含一些与Aero相关的功能,例如确定Aero是否已启用,以及能够启用和禁用Aero - 但这似乎是系统范围的更改,而不是每个窗体/窗口基础,它也导致屏幕延迟,而主题改变,这是不好的.
我不确定在这一点上去哪里.我可能忽略了一些简单的事情吗?我们是否需要创建和覆盖我们自己的TForm以及一些特定的标志等来实现这一点,或者可能有一种方法可以在任何时候改变表单样式,例如为表单启用/禁用Aero?
简单地说,我想知道如果不使用MDI应用程序是否可行,我们是否可以将任何窗体/窗口边框更改为Windows Basic主题,只要首先启用Aero?
我需要在设计时获取表单上的所有组件的列表(不是控件,只是组件).
组件也必须在表单上作为设计时的24x24图像可见.
我可以使用这样的代码
procedure TForm2.GetComponentList(Memo1: TMemo)
var
i: Integer;
begin
for i := 0 to ComponentCount-1 do
if (Components[i] is TComponent) and not (Components[i] is TControl) then
Memo1.Lines.Add(Components[i].Name);
end;
Run Code Online (Sandbox Code Playgroud)
但在这里我会得到像TField等隐形组件.
我只需要IDE在Form上显示的组件为24x24位图.
可能我可以使用Open Tools API吗?
这个问题已经困扰了我一段时间了,也许答案很简单,或者它可能涉及更多的VCL黑客或魔法来完成我正在寻找的东西,但无论哪种方式我都不知道如何解决我的问题问题.
如果您查看Delphi表单设计器,您将看到当鼠标移过它们时没有任何控件生成动画,它们也无法接收焦点或输入(例如,您无法键入TEdit,单击TCheckBox或移动TScrollBar等),仅在运行时,控件才能正常运行并响应用户交互.
我想知道如何在运行时对任何控件实现这种类型的行为,例如将控件设置为Designer State Mode?然而,控制也还是应该响应鼠标事件,如OnMouseDown,OnMouseMove,OnMouseUp等,使他们可以移动,如果需要,例如大小.
这是我管理的最接近的:
procedure SetControlState(Control: TWinControl; Active: Boolean);
begin
SendMessage(Control.Handle, WM_SETREDRAW, Ord(Active), 0);
InvalidateRect(Control.Handle, nil, True);
end;
Run Code Online (Sandbox Code Playgroud)
这可以简单地称为:
procedure TForm1.chkActiveClick(Sender: TObject);
begin
SetControlState(Button1, chkActive.Checked);
SetControlState(Button2, chkActive.Checked);
SetControlState(Edit1, chkActive.Checked);
end;
Run Code Online (Sandbox Code Playgroud)
或者,例如,表单上的所有控件:
procedure TForm1.chkActiveClick(Sender: TObject);
var
I: Integer;
Ctrl: TWinControl;
begin
for I := 0 to Form1.ControlCount -1 do
begin
if Form1.Controls[I] is TWinControl then
begin
Ctrl := TWinControl(Form1.Controls[I]);
if (Ctrl <> nil) and not (Ctrl = chkActive) then
begin
SetControlState(Ctrl, chkActive.Checked);
end; …Run Code Online (Sandbox Code Playgroud) 我需要创建自己的面板,这个面板将派生自TCustomPanel- 在这里,我将在面板上进行自己的自定义绘画,例如在顶部绘制标题.
我需要的一个要求是,我需要能够根据我的面板是否有焦点来绘制两种不同的颜色,我还需要一种方法来了解我的面板中的儿童控件是否也有焦点 - 当然虽然不知道孩子的内容是什么.
因此,例如,如果面板(或面板内的任何子控件)具有焦点,则颜色可以是clSkyBlue.如果面板(或面板内没有任何子控件)没有焦点,那么颜色可能是clWhite.
以下是自定义面板的快速布局:(为了保持简单,示例中没有标题绘图,只是基本的颜色变化)
type
TMyPanel = class(TCustomPanel)
private
//
protected
// procedure Paint; override;
procedure WMMouseDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;
constructor TMyPanel.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Self.ParentBackground := False;
Self.ParentColor := False;
end;
destructor TMyPanel.Destroy;
begin
inherited Destroy;
end;
procedure TMyPanel.WMMouseDown(var Message: TWMLButtonDown);
begin
Self.SetFocus;
end;
procedure TMyPanel.WMKillFocus(var Message: …Run Code Online (Sandbox Code Playgroud) 我想在Firemonkey项目的TPaintbox画布上绘制一个虚线网格,结果应该是这样的:
首先,我想我会绘制垂直虚线,然后绘制水平虚线,所以考虑到这一点,我试图首先绘制一条线以试图使外观恰到好处,这就是我尝试的:
Canvas.Stroke.Color := TAlphaColorRec.Black;
Canvas.Stroke.Dash := TStrokeDash.Dot;
Canvas.Stroke.Kind := TBrushKind.Solid;
Canvas.Stroke.Thickness := 1;
Canvas.DrawLine(PointF(0, 0), PointF(0, 150), 1);
Run Code Online (Sandbox Code Playgroud)
结果不是我所希望的,事实上TLine形状可以做我想要的虚线:
但我需要在画布上绘制自己,而不是使用其他控件.对于记录,TLine只需要将Stroke.Dash属性更改为Dot.
因此,在Firemonkey项目中使用画布我如何画一条虚线,就像TLine我可以像第一个样本图像一样绘制网格?
我是Visual Studio 2015和C#的初学者,我正在寻找一些我在其他任何地方都找不到的一般建议,所以请耐心等待.
假设我在解决方案资源管理器中创建了一个新的Windows窗体应用程序,我已经可以看到Form1.cs已添加到树中了,而且这个是Form1.Designer.cs和Form1.
现在我想通过右键单击WindowsFormApplication1和Add> 添加另一个表单New Item...
解决方案资源管理器现在看起来像这样:
对于我的第一个C#项目,我正在重新创建记事本,这不应该过于困难,这将使我熟悉语言和语法等.
我在项目中添加了第二个表单,它是Go To行号表单,显示在记事本的"编辑"菜单中.
假设我想给Form1和Form2更有意义的名称是什么做到这一点的正确方法是什么?
从属性检查器我命名Form1为frmMain和Form2,frmGoTo但我注意到在解决方案资源管理器中,父名称仍然是Form1.cs和Form2.cs:
所以我右键单击每个父节点并重命名它们,如下所示:
我现在的问题是这是正确还是错误的做法?我觉得我可能会有命名冲突.
为了测试我尝试显示这样的frmGoTo表单:
Form frmGoTo = new frmGoTo();
frmGoTo.ShowDialog();
Run Code Online (Sandbox Code Playgroud)
我认为我做得对,frmGoTo确实显示正确,但正如我所说,我对我从属性检查员和解决方案资源管理器重命名表单的方式表示怀疑.
我上面做了什么有什么问题,我是否应该为属性检查器表单名称和解决方案资源管理器名称等使用单独的命名约定?如上所述,我是否会遇到任何命名表单的问题?
我想我正在寻找一些清晰度,以便在解决方案中如何最好地重命名表单?
想象一下,使用单个位图水平和垂直平铺图块的画布,例如:
以上是通过以下方式实现的:
procedure TForm1.PaintBox1Paint(Sender: TObject);
var
X, Y: Integer;
begin
Y := 0;
while Y < PaintBox1.Height do
begin
X := 0;
while X < PaintBox1.Width do
begin
PaintBox1.Canvas.Draw(X, Y, Image1.Picture.Bitmap);
Inc(X, Image1.Picture.Bitmap.Width);
end;
Inc(Y, Image1.Picture.Bitmap.Height);
end;
PaintBox1.Canvas.Brush.Style := bsClear;
PaintBox1.Canvas.Rectangle(PaintBox1.ClientRect);
end;
Run Code Online (Sandbox Code Playgroud)
现在我想要做的是扩展上面的内容以允许水平和垂直偏移来模拟使用滚动条等时平铺图像被包装/滚动的效果.
这个想法是,例如,当更改水平偏移时,平铺图像将向左移动,而从右侧开始,您应该看到平铺图像看起来好像已经从绘图框的一侧缠绕到另一侧.
我已经设法制作了一个测试项目,它可以按照我的要求运行,它看起来像这样:
我已经在Lazarus中编写了这个测试项目,但它很容易适应Delphi中的测试.
下面是lfm:
object Form1: TForm1
Left = 0
Height = 625
Top = 0
Width = 782
Caption = 'Form1'
ClientHeight = 625
ClientWidth = 782
OnCreate = FormCreate
Position = poScreenCenter
Visible = False …Run Code Online (Sandbox Code Playgroud) 我有一个绘制在绘图箱上的图像,我希望能够在绘图框的任何给定区域上方显示一个半透明的填充矩形,它将以更深的颜色显示底部的绘图板画布,有点像Windows资源管理器中的选择框.
经过多次试验和错误(以及一些阅读),我设法做了以下事情:
procedure OpacityRectangle(ACanvas: TCanvas; ARect: TRect; AColor: TColor;
AOpacity: Integer);
var
BlendFunc: BLENDFUNCTION;
W, H: Integer;
Bitmap: TBitmap;
begin
W := ARect.Width;
H := ARect.Height;
BlendFunc.BlendOp := AC_SRC_OVER;
BlendFunc.BlendFlags := 0;
BlendFunc.SourceConstantAlpha := AOpacity;
BlendFunc.AlphaFormat := 0;
Bitmap := TBitmap.Create;
try
Bitmap.PixelFormat := pf32Bit;
Bitmap.SetSize(W, H);
BitBlt(Bitmap.Canvas.Handle, ARect.Left + W, ARect.Top + H, W, H,
ACanvas.Handle, 0, 0, SRCCOPY);
AlphaBlend(ACanvas.Handle, ARect.Left, ARect.Top,
W, H, Bitmap.Canvas.Handle, 0, 0, W, H, BlendFunc);
finally
Bitmap.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
正如您所看到的那样,AColor参数未被使用,因为我不确定如何在上面实现它.目前alpha混合矩形的颜色是灰色阴影(我假设默认颜色),我需要知道如何更改alpha混合矩形的色调颜色.
如何修改上述内容以允许为着色的alpha混合矩形选择自定义颜色?
我想创建一个自定义控件,TCustomControl从中我将覆盖该Paint方法并绘制诸如渐变背景,图形和形状等的东西,然后最终在它的顶部放置一个网格.
我知道所有这些都可能很慢,所以为了优化它,我想到了使用线程,例如一个线程来绘制背景,一个线程用于绘制形状,一个线程用于绘制网格,但我不太自信正确理解和实施它.
通过试验和错误,并查看一些线程示例(虽然我永远找不到任何好的线程绘画示例)我设法提出以下这将是我的通用线程类:
type
TCanvasThread = class(TThread)
private
FOnThreadPaint: TNotifyEvent;
FCanvas: TCanvas;
protected
procedure Execute; override;
procedure Sync;
public
constructor Create(Canvas: TCanvas; OnPaint: TNotifyEvent);
destructor Destroy; override;
property Canvas: TCanvas read FCanvas;
end;
constructor TCanvasThread.Create(Canvas: TCanvas; OnPaint: TNotifyEvent);
begin
inherited Create(False);
FreeOnTerminate := True;
FCanvas := Canvas;
FOnThreadPaint := OnPaint;
end;
destructor TCanvasThread.Destroy;
begin
inherited Destroy;
end;
procedure TCanvasThread.Execute;
begin
if Assigned(FOnThreadPaint) then
Synchronize(Sync);
end;
procedure TCanvasThread.Sync;
begin
FOnThreadPaint(Self);
end;
Run Code Online (Sandbox Code Playgroud)
以上是在自定义控件中实现的,如下所示:
type
TMyControl = class(TCustomControl)
private …Run Code Online (Sandbox Code Playgroud) 我已经创建了一个服务exe,它将在启动时自动运行.
我正在使用此示例来创建服务:http: //www.cromis.net/blog/2011/04/how-to-make-a-very-small-windows-service-executable/
效果很好.该服务需要"监控"PC的状态,例如检查PC是否连接到电源.如果发生变化,例如从连接电源到电池或电池电量不足,它将发送有关设备临界状态的紧急电子邮件.
当作为普通的exe运行但不作为服务运行时,这非常有效.目标是能够在PC的任何状态(登录或不登录)中执行此操作,因此必须作为服务运行.
我创建了一个窗口句柄来接收WM_POWERBROADCAST消息,例如:
procedure TEventAlerter.wndProc(var Msg : TMessage);
var
handled: Boolean;
begin
log( 'wndProc processed - '+intToStr( Msg.Msg ));
// Assume we handle message
handled := TRUE;
case( Msg.Msg ) of
WM_POWERBROADCAST : begin
case( Msg.WParam ) of
PBT_APMPOWERSTATUSCHANGE : powerChangeEvent(Msg.WParam);
PBT_APMBATTERYLOW : powerLowEvent(Msg.WParam);
else powerEvent(Msg.WParam);
end;
end;
else handled:= FALSE;
end;
if( handled ) then
begin
// We handled message - record in message result
Msg.Result := 0
end
else
begin
// We didn't …Run Code Online (Sandbox Code Playgroud) 概观
我试图枚举所有可见窗口名称的列表,然后填充作为参数传递的列表.
在Delphi中,我能够使用以下内容:
function EnumWindowNamesProc(wHandle: HWND; List: TStrings): BOOL; stdcall;
var
Title: array[0..255] of Char;
begin
Result := False;
GetWindowText(wHandle, Title, 255);
if IsWindowVisible(wHandle) then
begin
if Title <> '' then
begin
List.Add(string(Title));
end;
end;
Result := True;
end;
Run Code Online (Sandbox Code Playgroud)
然后我可以这样调用上面的内容:
EnumWindows(@EnumWindowNamesProc, LPARAM(FWindowNames));
注意:FWindowNames是在自定义类中创建的字符串列表.
问题
我也试图使该功能与Lazarus/FPC兼容,但它不接受List: TStrings参数.
Lazarus中的编译器错误抱怨类型不匹配(我突出了重要部分):
错误:arg no的类型不兼容.1:得到"(函数的地址(LongWord; TStrings):LongBool; StdCall)",""(函数的过程变量类型(LongWord; LongInt):LongBool; StdCall)"
我可以通过改变函数声明来阻止编译器抱怨:
{$IFDEF FPC}
function EnumWindowNamesProc(wHandle: HWND; Param: LPARAM): BOOL; stdcall;
{$ELSE}
function EnumWindowNamesProc(wHandle: HWND; List: TStrings): BOOL; stdcall;
{$ENDIF} …Run Code Online (Sandbox Code Playgroud) delphi ×10
delphi-xe7 ×3
lazarus ×3
aero ×1
api ×1
c# ×1
components ×1
design-time ×1
firemonkey ×1
ide ×1
power-state ×1
service ×1
themes ×1
windows ×1