小编Jas*_*son的帖子

Firemonkey(FMX)位图和颜色

假设我在Firemonkey中有一个小位图(例如32x24像素).所以我把一个TImage放到一个表单上,在构造函数中有这样的代码:

  Image1.Bitmap.Create(32, 24);
  if Image1.Bitmap.Canvas.BeginScene then
  try
    Image1.Bitmap.Canvas.Fill.Color := claBlack;
    Image1.Bitmap.Canvas.Stroke.Color := claYellow;
    Image1.Bitmap.Canvas.FillRect(RectF(0,0,32,24), 0, 0, AllCorners, $FF);
    Image1.Bitmap.Canvas.DrawLine(PointF(1,1), PointF(10,10), $FF);
  finally
    Image1.Bitmap.Canvas.EndScene;
    Image1.Bitmap.BitmapChanged;
  end;
Run Code Online (Sandbox Code Playgroud)

这在blackground上绘制了一条漂亮的对角线.

我想要做的是现在解析位图以确定受线条绘制影响的像素.如果我使用以下方法逐像素检查:

  for y := 0 to 23 do
    for x := 0 to 31 do
      if Image1.Bitmap.Pixels[x,y] <> claBlack then
        memo1.Lines.Add(Format('x=%d. y=%d. c=%x', [x,y,Image1.Bitmap.Pixels[x,y]]));
Run Code Online (Sandbox Code Playgroud)

输出到我的备忘录是:

x=0. y=0. c=FF3C3C00
x=1. y=0. c=FF3C3C00
x=0. y=1. c=FF3C3C00
x=1. y=1. c=FFE7E700
x=2. y=1. c=FF3C3C00
x=1. y=2. c=FF3C3C00
x=2. y=2. c=FFE7E700
x=3. y=2. c=FF3C3C00
x=2. y=3. c=FF3C3C00
x=3. y=3. …
Run Code Online (Sandbox Code Playgroud)

delphi delphi-xe2 firemonkey

35
推荐指数
2
解决办法
6370
查看次数

传递记录参数而不首先将其声明为变量

如果我试图调用一个记录类型(不是对象)作为参数的过程,是否有可能以某种方式传递该参数"inline"的细节而不必先声明该类型的变量?

假设我有这种简单的记录类型:

type TMyRecord = record
  AString: string;
  AnInt: Integer;
end;
Run Code Online (Sandbox Code Playgroud)

和这个程序声明:

procedure MyProcedure(Rec: TMyRecord);
Run Code Online (Sandbox Code Playgroud)

如果我想调用MyProcedure,我必须声明TMyRecord类型的变量,或者我可以执行以下操作:

MyProcedure(TMyRecord("Test", 10));
Run Code Online (Sandbox Code Playgroud)

这不起作用(XE2)(得到关于它的编译器错误,期望")").

那么,我可以这样做吗?或者不可能.

谢谢

delphi delphi-xe2

23
推荐指数
3
解决办法
8353
查看次数

通过Ajax Post更新模型更改视图 - MVC3

我正在尝试使用Ajax(我认为)调用来更新我的模型值,然后将新值反映在视图中.我现在只是将它用于测试目的.

这是概述:

模型

public class MyModel
{
    public int Integer { get; set; }
    public string Str { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

CONTROLLER

    public ActionResult Index()
    {
        var m = new MyModel();
        return View("Test1", m);
    }

    [HttpPost]
    public ActionResult ChangeTheValue(MyModel model)
    {
        var m = new MyModel();
        m.Str = model.Str;
        m.Str = m.Str + " Changed! ";
        m.Integer++;

        return View("Test1", m);

    }
Run Code Online (Sandbox Code Playgroud)

视图

  @model Test_Telerik_MVC.Models.MyModel
@using Test_Telerik_MVC.Models
@{
    ViewBag.Title = "Test1";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>
    Test1</h2>
@if (false)
{ …
Run Code Online (Sandbox Code Playgroud)

asp.net razor asp.net-mvc-3

22
推荐指数
1
解决办法
4万
查看次数

EmptyParam现在变量是一个函数 - 如何解决遗留代码?

我只是将Delphi 6中编写的一些旧代码升级到Delphi XE2.不幸的是,代码引用了Word97 COM对象来生成一些.doc文档.代码中有Word97的直接使用子句.

我必须保持生成的文档与旧的Crystal Report和另一个需要文档格式的第三方应用程序使用的Word格式相同.

所以,问题.因为我在uses子句中使用Word97,所以编译器抱怨每当使用EmptyParam变量时,实际和正式var参数的类型必须相同.这直接来自Word97.pas源文件.这是因为现在将EmptyParam声明为函数而不是变量.

处理这个问题的最佳方法是什么?我应该将Delphi 6源文件(Word97.pas等)复制到我的本地目录中,直接将它们与System.Variants.pas一起添加到我的项目中,并将我的应用程序的编译器指令更改为包含EMPTYPARAM_VAR吗?我没有尝试过,但希望它会将EmptyParam声明为变量.或者也许有一个更简单的解决方案.

谢谢

编辑

这里有更多的背景信息,即使我已经接受了答案,以备将来参考.这是代码的一个例子(AddClaimsLetter是"应用程序"COM对象 - 即TWordApplication):

AddClaimsLetter.Documents.Open(Wordfile, EmptyParam, EmptyParam,
                        EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam,
                        EmptyParam, EmptyParam, EmptyParam, EmptyParam);
Run Code Online (Sandbox Code Playgroud)

在不改变任何内容的情况下,此处的EmptyParam参数在编译时失败,表示"E2033实际和正式var参数的类型必须相同".

但是,因为我想保留Word97(在Delphi 6 Ent.安装文件夹中的OCX/Server中),我确实需要将.pas文件复制到我的本地项目文件中并声明一个用于代替EmptyParam的变量(因为这些文件也试图编译,我得到了与上面相同的编译器错误).

所以现在都在工作,但我可能会与管理层讨论升级到此应用程序的Office的更高版本!

谢谢

delphi com

11
推荐指数
2
解决办法
3965
查看次数

何时手动释放线程

如果我从主线程创建(挂起)线程:

  with TMyThread.Create(True) do
  begin
    OnTerminate := ThreadTerminated;
    FreeOnTerminate := False;
    Start;
  end;
Run Code Online (Sandbox Code Playgroud)

一旦完成,我该如何解放该实例?(即执行过程已完成执行 - 假设我已捕获异常).

这种破坏tthread对象链接的正确方法显示了一种方法(通过PostMessage过程),它工作正常并且有意义.但是,如果我创建线程并且我没有表单的句柄或我可以调用PostMessage过程的东西,该怎么办?例如,我在直接来自TObject的类中创建线程?

TMyClass = class
public
  procedure DoSomething;
end;

TMyClass.DoSomething;
begin
      with TMyThread.Create(True) do
      begin
        OnTerminate := ThreadTerminated;
        FreeOnTerminate := False;
        Start;
      end;  
end;
Run Code Online (Sandbox Code Playgroud)

所以,我想,如何在不访问表单句柄的情况下释放一个线程?

谢谢

delphi delphi-xe2

8
推荐指数
1
解决办法
5492
查看次数

Datasnap和SocketError

我有一个带有vcl表单客户端的datasnap服务器.从客户端,如果服务器已经说出关闭并使用现有客户端连接重新启动,我该如何处理?此方案引发10053 EIdSocketError异常.

为了复制,我运行服务器和客户端,调用服务器(我使用通过DataSnap代理生成器公开的方法)成功.然后我关闭服务器(例如关闭应用程序)并重新启动它.然后我再次尝试拨打服务器.

例如: 客户呼叫

    sm := TsvrPolicySearchClient.Create(datClientDB.SQLConnection1.DBXConnection);
    try
      ds := sm.SearchPolicyByPolicy(40, WCRef, '', 3);
      dspPolicyGroup.DataSet := ds;

      if cdsPolicyGroup.Active then
        cdsPolicyGroup.Refresh
      else
        cdsPolicyGroup.Open;

    finally
      sm.Free;
    end;
Run Code Online (Sandbox Code Playgroud)

dspPolicyGroup是一个TDataSetProvider,cdsPolicyGroup是一个TClientDataSet(我只是在本地使用它来"存储"我的TDataSet结果).

服务器

function TsvrPolicySearch.SearchPolicyByPolicy(AClientId: Integer; WCRefNum, ClientRef: string; SearchMethod: Integer): TDataSet;
begin
  spPolicyByWCRef.Close;
  spPolicyByWCRef.ParamByName('p_client').AsInteger := AClientId;
  spPolicyByWCRef.ParamByName('p_search_method').AsInteger := SearchMethod;
  spPolicyByWCRef.ParamByName('p_wc_refno').AsString := WCRefNum;
  spPolicyByWCRef.Open;
  Result := spPolicyByWCRef;
end;
Run Code Online (Sandbox Code Playgroud)

我认为人们经常会遇到这种情况很容易复制.我应该在每次调用之前首先进行"测试连接"调用(例如方法TestConnection)以检查EIdSocketError(和等效的)并处理?或者它更像是一个设计缺陷?

谢谢

delphi datasnap delphi-xe2

7
推荐指数
1
解决办法
2167
查看次数

如何显示类似于Delphi XE工具提示代码洞察力的工具提示或提示

我正在考虑实现一个工具提示,类似于Delphi XE在您调试时将其悬停在对象上的方式.即,它打开一个带有+符号的提示窗口,您可以展开等.

我正在尝试创建一个提示窗口,当鼠标悬停在控件(例如按钮)上时,它将显示一个项目列表(例如),该控件将允许用户点击某个项目,然后我可以根据项目执行某些操作他们选择了.

是否有任何组件可能已经这样做了?或者我最好只创建一个无边框表单并处理显示/隐藏自己的鼠标事件?

谢谢

贾森

delphi components tooltip

5
推荐指数
1
解决办法
2539
查看次数

InputBuffer中的Indy TCPClient和流氓字节

我使用以下几行代码通过IP从外部调制解调器/路由器(也称为设备)进行写入和读取.

TCPClient.IOHandler.Write(MsgStr);
TCPClient.IOHandler.InputBuffer.Clear; 
TCPClient.IOHandler.ReadBytes(Buffer, 10, True);
Run Code Online (Sandbox Code Playgroud)

MsgStr是一种字符串类型,其中包含我发送到设备的文本.缓冲区声明为TIdBytes.我可以确认IOHandler.InputBufferIsEmpty在调用ReadBytes之前立即返回True.

我期待收到的前10个字节非常具体,因此从我的观点来看,我只对我发送字符串后收到的前10个字节感兴趣.

我遇到的麻烦是,在与某些设备通信时,第一次在建立连接后发送字符串时返回第一个字节会在我的缓冲区输出中放入一个流氓(随机)字节.后续的后续字节是正确的.

例如,我期待的10个字节可能是:#6A1EF1090#3但我得到的是#6A1EF1090.在这个例子中,我有一个句号,不应该有一个.

如果我再次尝试发送,它工作正常.(即在建立连接后发送的第二个写入).奇怪(对我来说)使用Socket Sniffer并不会显示返回的随机字节.如果我创建自己的"服务器"来接收响应并发回一些东西,它可以100%正常工作.其他软件 - 也就是说,不是我的软件 - 与设备进行良好的通信(当然我不知道他们是如何解析数据的).

是否有任何我正在做错误的事情导致这种情况 - 请记住它只发生在我建立连接后第一次使用Write时?

谢谢

编辑

我正在使用Delphi 7和Indy 10.5.8

UPDATE

好.经过多次测试和观察后,我无法找到这个解决方案.我有两个主要方案.1 - 第一个字节丢失,2 - 在接收数据包开始时"引入"字节.使用TIdLogEvent和TIdLogDebug都会根据需要显示丢失的字节或初始引入的字节.所以我上面的ReadBytes声明一直在显示Indy认为的内容(在我看来).

另外,为了进一步测试,我下载并安装了ICS组件.不幸的是(或者幸运的是取决于你如何看待它),这并没有显示出与Indy相同的问题.这没有显示丢失的第一个字节,也没有显示开头的引入字节.然而,我只做了表面测试,但是Indy产生了"非常直接"的行为,而ICS还没有产生它.

如果有人有兴趣,我可以提供一个小型演示应用程序,说明问题和我连接的IP - 这是一个公共IP,所以任何人都可以访问它.否则现在,我只需要解决它.我不愿意切换到ICS,因为ICS可能在这种情况下正常工作,并且考虑到使用这个套接字的东西几乎是该程序的全部关键,因此必须用ICS完全取代Indy是令人讨厌的.

delphi tcp delphi-7 indy10

5
推荐指数
1
解决办法
1941
查看次数

Delphi XE2 - 嵌套类函数无法编译

我正在将一些传统的第三方组件从Delphi 6源升级到XE2.

第三方源在类过程中具有嵌套的类函数.模拟将失败的确切工作副本:

type
  TMyClass1 = class
  public
    class procedure DoSomething;
  end;

{ TMyClass1 }

class procedure TMyClass1.DoSomething;
  class function DoSomethingelse: boolean;
  begin
    result := false;
  end;
begin

end;
Run Code Online (Sandbox Code Playgroud)

尝试编译这会给出一个关于doSomethingelse是未声明的标识符的错误.现在我可以(大概)通过将嵌套函数拉出到同一级别来解决这个问题,但是我可以设置一个编译器选项来防止这种情况吗?这是最近改变了吗?还有其他人遇到过这个问题吗?

谢谢

delphi delphi-xe2

4
推荐指数
1
解决办法
601
查看次数

为什么在通过OnClose事件(在线程中)释放表单后不显示MessageDlg

鉴于这种情况:

procedure TForm2.Button1Click(Sender: TObject);
var
  Form: TForm;
begin
  Form := TForm.Create(nil);
  Form.OnClose := FormClosed;
  Form.Show;
  Sleep(200);
  TThread.CreateAnonymousThread(
    procedure
    begin
      TThread.Synchronize( nil, 
        procedure 
        begin 
          Form.Close; 
          MessageDlg('Testing', mtInformation, [mbok], 0); 
        end);
    end).Start;
end;

procedure TForm2.FormClosed(Sender: TObject; var Action: TCloseAction);
begin
  Action := TCloseAction.caFree;
end;
Run Code Online (Sandbox Code Playgroud)

我的MessageDlg调用未显示(此调用的结果始终为mrCancel(2)).

在挖掘之后,它与OnClose事件相关并将Action设置为caFree.

改变Form.CloseForm.Free和删除OnClose事件完全显示的MessageDlg确定.在调用Form.Close 之前放置MessageDlg 可以正常工作.最初我认为我的Form变量的范围可能导致了问题,但Form在TForm2实例中声明为私有字段并不能解决问题.

我的目标是显示一个启动窗体,执行我的线程,然后通过所述线程的回调,关闭Splash窗体并在适当的位置显示对话框.

为清楚起见,为什么会这样?

delphi multithreading dialog delphi-xe6

4
推荐指数
1
解决办法
227
查看次数