Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 为什么插入符号突然在编辑字段中居中?_Delphi - Fatal编程技术网

Delphi 为什么插入符号突然在编辑字段中居中?

Delphi 为什么插入符号突然在编辑字段中居中?,delphi,Delphi,我在Delphi 2006登录表单上有一个“用户名”TEdit。当应用程序启动时,要求用户输入用户名。TEdit获得焦点,插入符号出于某种原因被放置在其水平中心。一旦输入任何内容,插入符号将再次左对齐,所有内容看起来都正常 奇怪的是,事情并非总是这样。这种行为几年前突然开始(我相信当时我们仍然使用Delphi6)。你知道是什么引起的吗 其他信息(已要求): 这个问题很普遍:D2006和D6(我相信),在尽可能多的计算机上有5或6个Delphi实例,所有应用程序都使用该登录表单。该效果仅限于形式,

我在Delphi 2006登录表单上有一个“用户名”TEdit。当应用程序启动时,要求用户输入用户名。TEdit获得焦点,插入符号出于某种原因被放置在其水平中心。一旦输入任何内容,插入符号将再次左对齐,所有内容看起来都正常

奇怪的是,事情并非总是这样。这种行为几年前突然开始(我相信当时我们仍然使用Delphi6)。你知道是什么引起的吗

其他信息(已要求):
  • 这个问题很普遍:D2006和D6(我相信),在尽可能多的计算机上有5或6个Delphi实例,所有应用程序都使用该登录表单。该效果仅限于形式,但不会出现在其他TEDIT上
  • TEdit中没有填充空格(一开始这样做会很奇怪)

  • 更多信息(11月13日):
  • 插入符号没有完全居中,它几乎居中
  • 目前,它似乎只出现在DLL中。在常规可执行文件中使用了相同的登录对话框,并且没有显示问题(尽管我相信它在某些时候显示过)
  • 编辑字段是密码编辑,OnChange处理程序仅设置该形式的整数字段,该编辑字段上没有其他事件处理程序
  • 我添加了另一个普通的TEdit,它也是ActiveControl,以便在表单显示时具有焦点(就像密码编辑一样)。我还删除了默认文本“Edit1”。现在问题以同样的方式出现在TEdit中

  • “居中”插入符号返回正常状态,如果输入字符或通过控件进行制表-当我返回TEdit时,它看起来正常。这与密码编辑相同。
  • 还有几个问题:

  • 这是一台电脑上的问题还是多台电脑上的问题
  • 它发生在一个应用程序上还是所有应用程序上
  • 它是只发生在Delphi应用程序上还是发生在所有应用程序上
  • 如果它只在一台电脑上,我认为这是一个奇怪的注册表设置。如果它在多台pc上,但您只有一台delphi开发pc,它仍然可能是一个注册表设置。但还有其他可能性

    您可以尝试一些测试:

  • 在dev pc上创建一个简单的应用程序,并在另一台pc上运行。这是否显示了效果
  • 使用Delphi创建的应用程序,但在另一台未显示效果的pc上构建,并在dev pc上运行,这是否显示效果
  • 我真的认为这是一个注册表设置。根据你给我的信息,它发生在Delphi 6之后,现在仍在发生。 它也可以是区域设置,但必须在更多的程序中进行

    编辑: 谢谢你提供的额外信息。 因此,看起来问题可以孤立成一种形式。但它发生在所有的个人电脑上

    您可以做的是删除编辑,然后重新添加一个新的编辑。这样可以避免搜索奇怪的属性值

    • TEdit上是否有可以解释其影响的事件
    • 设置了哪些属性值?(但我更喜欢看dfm和代码,因为这样我就可以重现效果。)

      • 你确定这是一个简单的TEdit吗?它可以用几个空格而不是空字符串初始化。一旦您开始键入,onChange处理程序可能会立即删除空格。 TEdit扩展可以将文本对齐设置为居中而不是左对齐,并且仅在onChange上设置文本对齐

        [编辑]
        请显示TEdit的事件处理程序。

        我在richedits中也注意到了这种行为

        我们应用程序中的一个地方是双击一个网格,该网格显示另一个包含RichEdit的屏幕。插入符号似乎总是出现在Richedit中与双击网格发生的位置相同的位置,即如果dblclick位于网格的第三行,则插入符号将在编辑上向下显示约3行。只要按下一个键,插入符号就会重置到左上角的正确位置

        它不仅限于某种形式或pc机,因为它发生在所有开发人员的机器上,也发生在客户机上。 该应用程序最初是在Delphi5中开发的,但直到我们转到D2006后,问题才出现(或没有被注意到)


        这不是一个特别大的问题,只是。。。恼人。

        我在Delphi 2007中也遇到了同样的问题,
        通过在网格中双击,将TEdit放置在一个模式形式中

        我做了一些测试,从TSpeedButton启动相同的表单。 我注意到TEdit的问题只有在网格聚焦时才会出现

        经过更多测试后,问题似乎是VCL中的一个错误
        在TCustomGrid.paint中,即使网格不在活动窗体上,也会调用SetCaretPos

              ../..
              Focused := IsActiveControl;
              if Focused and (CurRow = Row) and (CurCol = Col)  then
              begin
                SetCaretPos(Where.Left, Where.Top);          
                Include(DrawState, gdFocused);
              end;
              ../.. 
        
        上面的代码来自Grids.pas中的TCustomGrid.paint 在这段代码中,如果网格是父窗体的“activeControl”,则Focused设置为true,而代码不考虑窗体是否处于活动状态

        然后,如果需要重新绘制网格,将使用网格坐标调用setCaretPos,从而导致问题中提到的错误

        这个bug很难被注意到,因为在大多数情况下,插入符号只是从活动表单中消失,而不是在TEdit的中间闪烁

        复制错误的步骤:

      • 启动新的VCL表单应用程序
      • 将TStringGrid添加到其中
      • 在应用程序中添加第二个表单,其中只包含一个TEdit
      • 以主窗体(unit1)返回,并从grid DblClick事件调用form2.showmodel
      • 仅此而已:您可以启动应用程序并双击网格单元。 如果你拖动模态窗体离开主窗体,网格将需要重新绘制,然后导致插入符号从模态形式消失(或者如果你非常幸运地出现在TeDIT的中间)

        因此,我认为Grids.pas中需要一个修复程序

        在e
        // new function introduced to fix a bug
        // this function is a duplicate of the function IsActiveControl
        // with a minor modification (see comment)
        function TCustomGrid.IsFocusedControl: Boolean;
        var
          H: Hwnd;
          ParentForm: TCustomForm;
        begin
          Result := False;
          ParentForm := GetParentForm(Self);
          if Assigned(ParentForm) then
          begin
            if (ParentForm.ActiveControl = Self) then
              //Result := True;            // removed by DamienD
              Result := ParentForm.Active; // added by DamienD
          end
          else
          begin
            H := GetFocus;
            while IsWindow(H) and (Result = False) do
            begin
              if H = WindowHandle then
                Result := True
              else
                H := GetParent(H);
            end;
          end;
        end;
        
        Gird.BeginUpdate;
        
        try
        
          //Show the second form here
        
        finally
        
          Grid.EndUpdate;
        
        end;