#define WM_ERASEBKGND                   0x0014

Parameters

wParam

A handle to the device context. // 设备上下文的句柄

lParam

This parameter is not used.

Return value

Type: LRESULT

An application should return nonzero if it erases the background; otherwise, it should return zero.

如果它擦除背景,函数返回非零值 ;否则,函数返回零。

Remarks

The DefWindowProc function erases the background by using the class background brush specified by the hbrBackgroundmember of the WNDCLASS structure. If hbrBackground is NULL, the application should process the WM_ERASEBKGNDmessage and erase the background.

DefWindowProc函数通过使用WNDCLASS结构中指定的hbrBackground背景画笔擦除背景。如果hbrBackground是空的,应用程序应该处理WM_ERASEBKGND消息擦除背景。

An application should return nonzero in response to WM_ERASEBKGND if it processes the message and erases the background; this indicates that no further erasing is required. If the application returns zero, the window will remain marked for erasing. (Typically, this indicates that the fErase member of the PAINTSTRUCT structure will be TRUE.)

如果应用程序响应处理WM_ERASEBKGND消息并擦除背景,应返回非零值 ;告诉Windows没有必要再擦除。如果应用程序返回零,Windows仍将标记为删除。(通常情况下,这表明PAINTSTRUCT结构中的fErase为真.)

翻译来自:http://baike.baidu.com/view/9801207.htm

------------------------------------------------------------------------------------------------------

这个消息在Delphi被重定义:

  1. TWMEraseBkgnd = packed record
  2. Msg: Cardinal;
  3. DC: HDC;
  4. Unused: Longint;
  5. Result: Longint;
  6. end;

它在Controls.pas单元里的相关代码(1处定义,2处使用):

  1. procedure TWinControl.WMEraseBkgnd(var Message: TWMEraseBkgnd);
  2. begin
  3. with ThemeServices do
  4. if ThemesEnabled and Assigned(Parent) and (csParentBackground in FControlStyle) then
  5. begin
  6. { Get the parent to draw its background into the control's background. }
  7. DrawParentBackground(Handle, Message.DC, nil, False);
  8. end
  9. else
  10. begin
  11. { Only erase background if we're not doublebuffering or painting to memory. }
  12. if not FDoubleBuffered or
  13. (TMessage(Message).wParam = TMessage(Message).lParam) then
  14. FillRect(Message.DC, ClientRect, FBrush.Handle);
  15. end;
  16.  
  17. Message.Result := 1; // 相当于说,WM_ERASEBKGND的传递到此为止,无论如何都不要继续传递了
  18. end;
  19. procedure TWinControl.WMPaint(var Message: TWMPaint);
  20. var
  21. DC, MemDC: HDC;
  22. MemBitmap, OldBitmap: HBITMAP;
  23. PS: TPaintStruct;
  24. begin
  25. if not FDoubleBuffered or (Message.DC <> 0) then
  26. begin
  27. if not (csCustomPaint in ControlState) and (ControlCount = ) then
  28. inherited
  29. else
  30. PaintHandler(Message);
  31. end
  32. else
  33. begin
  34. DC := GetDC(); // 整个屏幕的DC,借用一下而已
  35. MemBitmap := CreateCompatibleBitmap(DC, ClientRect.Right, ClientRect.Bottom); // 图像不宜过大,所以设置成最大就是屏幕大小
  36. ReleaseDC(, DC); // 还掉了
  37. MemDC := CreateCompatibleDC();
  38. OldBitmap := SelectObject(MemDC, MemBitmap);
  39. try
  40. DC := BeginPaint(Handle, PS); // 重新取得当前控件的DC
  41. Perform(WM_ERASEBKGND, MemDC, MemDC); // 结合上面的TWinControl.WMEraseBkgnd,可以观察到,要得就是这种效果,即双缓冲第一次绘制时候,需要删除背景
  42. Message.DC := MemDC; // 构建一个消息,把MemDC传入,当前控件和子控件都在MemDC上画,不在原先的DC上作画了
  43. WMPaint(Message); // 递归调用,会引发DC<>0的情况,从而正常绘制所有子控件(绘制子控件不需要双缓冲了),否则根本据不会进入绘制子控件的流程
  44. Message.DC := ; // 子控件绘制完毕,不管后续消息流动到何处,不要在消息包含的DC上绘制东西了
  45. BitBlt(DC, , , ClientRect.Right, ClientRect.Bottom, MemDC, , , SRCCOPY); // 把MemDC上的内容拷贝到DC上
  46. EndPaint(Handle, PS);
  47. finally
  48. SelectObject(MemDC, OldBitmap); // 还掉
  49. DeleteDC(MemDC); // 还掉
  50. DeleteObject(MemBitmap); // 还掉
  51. end;
  52. end;
  53. end;

还可以打印控件到其它DC设备上:

  1. // Draws the windowed control to a device context.
  2. procedure TWinControl.PaintTo(DC: HDC; X, Y: Integer);
  3. var
  4. I, EdgeFlags, BorderFlags, SaveIndex: Integer;
  5. R: TRect;
  6. begin
  7. Include(FControlState, csPaintCopy);
  8. SaveIndex := SaveDC(DC);
  9. MoveWindowOrg(DC, X, Y);
  10. IntersectClipRect(DC, , , Width, Height);
  11. BorderFlags := ;
  12. EdgeFlags := ;
  13. if GetWindowLong(Handle, GWL_EXSTYLE) and WS_EX_CLIENTEDGE <> then
  14. begin
  15. EdgeFlags := EDGE_SUNKEN;
  16. BorderFlags := BF_RECT or BF_ADJUST
  17. end else
  18. if GetWindowLong(Handle, GWL_STYLE) and WS_BORDER <> then
  19. begin
  20. EdgeFlags := BDR_OUTER;
  21. BorderFlags := BF_RECT or BF_ADJUST or BF_MONO;
  22. end;
  23. if BorderFlags <> then
  24. begin
  25. SetRect(R, , , Width, Height);
  26. DrawEdge(DC, R, EdgeFlags, BorderFlags);
  27. MoveWindowOrg(DC, R.Left, R.Top);
  28. IntersectClipRect(DC, , , R.Right - R.Left, R.Bottom - R.Top);
  29. end;
  30. Perform(WM_ERASEBKGND, DC, );
  31. Perform(WM_PAINT, DC, );
  32. if FWinControls <> nil then
  33. for I := to FWinControls.Count - do
  34. with TWinControl(FWinControls[I]) do
  35. if Visible then PaintTo(DC, Left, Top);
  36. RestoreDC(DC, SaveIndex);
  37. Exclude(FControlState, csPaintCopy);
  38. end;

------------------------------------------------------------------------------------------------------

Controls.pas里还有一处定义,但是它只有在TSpeedButton里被使用:

  1. procedure PerformEraseBackground(Control: TControl; DC: HDC);
  2. var
  3. LastOrigin: TPoint;
  4. begin
  5. GetWindowOrgEx(DC, LastOrigin);
  6. SetWindowOrgEx(DC, LastOrigin.X + Control.Left, LastOrigin.Y + Control.Top, nil);
  7. Control.Parent.Perform(WM_ERASEBKGND, Integer(DC), Integer(DC)); // TSpeedButton自己不是Windows窗口,只能出此下策
  8. SetWindowOrgEx(DC, LastOrigin.X, LastOrigin.Y, nil);
  9. end;
  10.  
  11. procedure TSpeedButton.Paint;
  12. const
  13. DownStyles: array[Boolean] of Integer = (BDR_RAISEDINNER, BDR_SUNKENOUTER);
  14. FillStyles: array[Boolean] of Integer = (BF_MIDDLE, );
  15. var
  16. PaintRect: TRect;
  17. DrawFlags: Integer;
  18. Offset: TPoint;
  19. Button: TThemedButton;
  20. ToolButton: TThemedToolBar;
  21. Details: TThemedElementDetails;
  22. begin
  23. if not Enabled then
  24. begin
  25. FState := bsDisabled;
  26. FDragging := False;
  27. end
  28. else if FState = bsDisabled then
  29. if FDown and (GroupIndex <> ) then
  30. FState := bsExclusive
  31. else
  32. FState := bsUp;
  33. Canvas.Font := Self.Font;
  34.  
  35. if ThemeServices.ThemesEnabled then
  36. begin
  37. PerformEraseBackground(Self, Canvas.Handle);
  38. // 其它代码
  39. end;
  40. end;

------------------------------------------------------------------------------------------------------

Forms.pas单元里的定义与使用:

  1. procedure TCustomForm.WMEraseBkgnd(var Message: TWMEraseBkgnd);
  2. begin
  3. if not IsIconic(Handle) then inherited else
  4. begin
  5. Message.Msg := WM_ICONERASEBKGND; // 当窗口处于最小化状态的时候,改变消息值
  6. DefaultHandler(Message); // 当窗口是MDI时,还应该改变当前窗口的图标,否则相当于不执行
  7. end;
  8. end;
  9.  
  10. procedure TCustomForm.ClientWndProc(var Message: TMessage);
  11.  
  12. procedure Default;
  13. begin
  14. with Message do
  15. Result := CallWindowProc(FDefClientProc, ClientHandle, Msg, wParam, lParam);
  16. end;
  17.  
  18. function MaximizedChildren: Boolean;
  19. var
  20. I: Integer;
  21. begin
  22. for I := to MDIChildCount - do
  23. if MDIChildren[I].WindowState = wsMaximized then
  24. begin
  25. Result := True;
  26. Exit;
  27. end;
  28. Result := False;
  29. end;
  30.  
  31. var
  32. DC: HDC;
  33. PS: TPaintStruct;
  34. R: TRect;
  35. begin
  36. with Message do
  37. case Msg of
  38. WM_NCHITTEST:
  39. begin
  40. Default;
  41. if Result = HTCLIENT then Result := HTTRANSPARENT;
  42. end;
  43. WM_ERASEBKGND:
  44. begin
  45. FillRect(TWMEraseBkGnd(Message).DC, ClientRect, Brush.Handle);
  46. { Erase the background at the location of an MDI client window }
  47. if (FormStyle = fsMDIForm) and (FClientHandle <> ) then
  48. begin
  49. Windows.GetClientRect(FClientHandle, R);
  50. FillRect(TWMEraseBkGnd(Message).DC, R, Brush.Handle);
  51. end;
  52. Result := ;
  53. end;
  54. $3F://!
  55. begin
  56. Default;
  57. if FFormStyle = fsMDIForm then
  58. ShowMDIClientEdge(FClientHandle, (MDIChildCount = ) or
  59. not MaximizedChildren);
  60. end;
  61. WM_PAINT:
  62. begin
  63. DC := TWMPaint(Message).DC;
  64. if DC = then
  65. TWMPaint(Message).DC := BeginPaint(ClientHandle, PS);
  66. try
  67. if DC = then
  68. begin
  69. GetWindowRect(FClientHandle, R);
  70. R.TopLeft := ScreenToClient(R.TopLeft);
  71. MoveWindowOrg(TWMPaint(Message).DC, -R.Left, -R.Top);
  72. end;
  73. PaintHandler(TWMPaint(Message));
  74. finally
  75. if DC = then
  76. EndPaint(ClientHandle, PS);
  77. end;
  78. end;
  79. else
  80. Default;
  81. end;
  82. end;

进一步解释TCustomForm.WMEraseBkgnd转发来的消息:

  1. procedure TCustomForm.DefaultHandler(var Message);
  2. begin
  3. if ClientHandle <> then
  4. with TMessage(Message) do
  5. if Msg = WM_SIZE then
  6. Result := DefWindowProc(Handle, Msg, wParam, lParam) else
  7. Result := DefFrameProc(Handle, ClientHandle, Msg, wParam, lParam)
  8. else
  9. inherited DefaultHandler(Message)
  10. end;
  11.  
  12. // 处理图标消息 message WM_ICONERASEBKGND
  13. procedure TCustomForm.WMIconEraseBkgnd(var Message: TWMIconEraseBkgnd);
  14. begin
  15. if FormStyle = fsMDIChild then
  16. if (FormStyle = fsMDIChild) and not (csDesigning in ComponentState) then
  17. FillRect(Message.DC, ClientRect, Application.MainForm.Brush.Handle)
  18. else inherited;
  19. end;

还有TApplication对这个消息的使用:

  1. procedure TApplication.WndProc(var Message: TMessage);
  2. var
  3. procedure Default;
  4. begin
  5. with Message do
  6. Result := DefWindowProc(FHandle, Msg, WParam, LParam);
  7. end;
  8.  
  9. begin
  10. try
  11. Message.Result := ;
  12. for I := to FWindowHooks.Count - do
  13. if TWindowHook(FWindowHooks[I]^)(Message) then Exit;
  14. CheckIniChange(Message);
  15. with Message do
  16. case Msg of
  17. WM_SYSCOMMAND:
  18. case WParam and $FFF0 of
  19. SC_MINIMIZE: Minimize;
  20. SC_RESTORE: Restore;
  21. else
  22. Default;
  23. end;
  24. WM_CLOSE:
  25. if MainForm <> nil then MainForm.Close;
  26. WM_PAINT:
  27. if IsIconic(FHandle) then DrawAppIcon else Default;
  28. WM_ERASEBKGND: // 改变消息,然后转发
  29. begin
  30. Message.Msg := WM_ICONERASEBKGND;
  31. Default;
  32. end;
  33. WM_NULL:
  34. CheckSynchronize;
  35. else
  36. Default;
  37. end;
  38. except
  39. HandleException(Self);
  40. end;
  41. end;

------------------------------------------------------------------------------------------------------

再看StdCtrls.pas单元里的定义与使用:

  1. procedure TCustomComboBox.WMEraseBkgnd(var Message: TWMEraseBkgnd);
  2. begin
  3. if Style = csSimple then
  4. begin
  5. FillRect(Message.DC, ClientRect, Parent.Brush.Handle);
  6. Message.Result := ;
  7. end
  8. else
  9. DefaultHandler(Message);
  10. end;
  11.  
  12. procedure TButtonControl.WMEraseBkGnd(var Message: TWMEraseBkGnd);
  13. begin
  14. { Under theme services the background is drawn in CN_CTLCOLORSTATIC. }
  15. if ThemeServices.ThemesEnabled then
  16. Message.Result :=
  17. else
  18. inherited;
  19. end;
  20.  
  21. procedure TButton.WMEraseBkgnd(var Message: TWMEraseBkgnd);
  22. begin
  23. if ThemeServices.ThemesEnabled then
  24. Message.Result :=
  25. else
  26. DefaultHandler(Message);
  27. end;
  28.  
  29. procedure TScrollBar.WMEraseBkgnd(var Message: TWMEraseBkgnd);
  30. begin
  31. DefaultHandler(Message);
  32. end;

------------------------------------------------------------------------------------------------------

还有ExtCtrls.pas单元里的:

  1. procedure TCustomControlBar.WMEraseBkgnd(var Message: TWmEraseBkgnd);
  2. var
  3. R: TRect;
  4. I, J: Integer;
  5. Save: Boolean;
  6. begin
  7. if Message.DC <> then
  8. Canvas.Handle := Message.DC;
  9. if Picture.Graphic <> nil then
  10. begin
  11.  
  12. try
  13. R := ClientRect;
  14. Save := FDrawing;
  15. FDrawing := True;
  16. try
  17. { Tile image across client area }
  18. for I := to (R.Right - R.Left) div Picture.Width do
  19. for J := to (R.Bottom - R.Top) div Picture.Height do
  20. Canvas.Draw(I * Picture.Width, J * Picture.Height, Picture.Graphic);
  21. finally
  22. FDrawing := Save;
  23. end
  24. finally
  25. if Message.DC <> then
  26. Canvas.Handle := ;
  27. Message.Result := ;
  28. end;
  29. end
  30. else
  31. begin
  32. Canvas.Brush.Color := Color;
  33. Canvas.Brush.Style := bsSolid;
  34. Canvas.FillRect(ClientRect);
  35. inherited;
  36. end;
  37. end;

------------------------------------------------------------------------------------------------------

还有dbcgrids.pas和DbCtrls.pas单元里的:

  1. procedure TDBCtrlPanel.WMEraseBkgnd(var Message: TMessage);
  2. begin
  3. Message.Result := ;
  4. end;
  5.  
  6. procedure TDBCtrlGrid.WMEraseBkgnd(var Message: TMessage);
  7. begin
  8. Message.Result := ;
  9. end;procedure TDBMemo.WMPaint(var Message: TWMPaint);
  10. var
  11. S: string;
  12. begin
  13. if not (csPaintCopy in ControlState) then inherited else
  14. begin
  15. if FDataLink.Field <> nil then
  16. if FDataLink.Field.IsBlob then
  17. begin
  18. if FAutoDisplay then
  19. S := AdjustLineBreaks(FDataLink.Field.AsString) else
  20. S := Format('(%s)', [FDataLink.Field.DisplayLabel]);
  21. end else
  22. S := FDataLink.Field.DisplayText;
  23. SendMessage(FPaintControl.Handle, WM_SETTEXT, , Integer(PChar(S)));
  24. SendMessage(FPaintControl.Handle, WM_ERASEBKGND, Message.DC, );
  25. SendMessage(FPaintControl.Handle, WM_PAINT, Message.DC, );
  26. end;
  27. end;

------------------------------------------------------------------------------------------------------

还有ShadowWnd.pas单元里的:

  1. procedure TShadowWindow.WMEraseBkgnd(var Message: TWMEraseBkgnd);
  2. begin
  3. Message.Result := ;
  4. end;

------------------------------------------------------------------------------------------------------

还有Tabs.pas单元里的:

  1. procedure TTabSet.Paint;
  2. var
  3. TabStart, LastTabPos: Integer;
  4. TabPos: TTabPos;
  5. Tab: Integer;
  6. Leading: TEdgeType;
  7. Trailing: TEdgeType;
  8. isFirst, isLast, isSelected, isPrevSelected: Boolean;
  9. R: TRect;
  10. begin
  11. if not HandleAllocated then Exit;
  12.  
  13. MemBitmap.Canvas.Font := Self.Canvas.Font;
  14.  
  15. { draw background of tab area }
  16. with MemBitmap.Canvas do
  17. begin
  18. Brush.Bitmap := BrushBitmap;
  19. if ThemeServices.ThemesEnabled and ParentBackground then
  20. Perform(WM_ERASEBKGND, MemBitmap.Canvas.Handle, )
  21. else
  22. FillRect(Rect(, , MemBitmap.Width, MemBitmap.Height));
  23.  
  24. end;
  25. end;

------------------------------------------------------------------------------------------------------

还有OleCtrls.pas单元里的:

  1. procedure TOleControl.WMEraseBkgnd(var Message: TWMEraseBkgnd);
  2. begin
  3. if FMiscStatus and OLEMISC_INVISIBLEATRUNTIME = then
  4. DefaultHandler(Message) else
  5. inherited;
  6. end;

------------------------------------------------------------------------------------------------------

还有ComCtrls.pas单元里的5处定义和2处使用:

  1. procedure TPageControl.WMEraseBkGnd(var Message: TWMEraseBkGnd);
  2. begin
  3. if (not ThemeServices.ThemesEnabled) or (not ParentBackground) then
  4. inherited
  5. else
  6. Message.Result := ;
  7. end;
  8.  
  9. procedure TCustomStatusBar.WMEraseBkGnd(var Message: TWMEraseBkGnd);
  10. var
  11. Details: TThemedElementDetails;
  12. begin
  13. if ThemeServices.ThemesEnabled then
  14. begin
  15. Details := ThemeServices.GetElementDetails(tsStatusRoot);
  16. ThemeServices.DrawElement(Message.DC, Details, ClientRect, nil);
  17. Message.Result := ;
  18. end
  19. else
  20. inherited;
  21. end;
  22.  
  23. procedure TTrackBar.WMEraseBkGnd(var Message: TWMEraseBkGnd);
  24. var
  25. R: TRect;
  26. begin
  27. if ThemeServices.ThemesEnabled then
  28. begin
  29. R := ClientRect;
  30. if Focused and ((Perform(WM_QUERYUISTATE, , ) and UISF_HIDEFOCUS) = ) then
  31. InflateRect(R, -, -);
  32. ThemeServices.DrawParentBackground(Handle, Message.DC, nil, False, @R);
  33. Message.Result := ;
  34. end
  35. else
  36. inherited;
  37. end;
  38.  
  39. procedure TToolBar.WMEraseBkgnd(var Message: TWMEraseBkgnd);
  40. begin
  41. if not Transparent then
  42. inherited else
  43. DefaultHandler(Message);
  44. end;
  45.  
  46. procedure TCoolBar.WMEraseBkgnd(var Message: TWMEraseBkgnd);
  47. begin
  48. if not ThemeServices.ThemesEnabled and (IsBackgroundDirty or (IsAutoSized and (Bands.Count = ))) then
  49. inherited;
  50. DefaultHandler(Message);
  51. end;
  52.  
  53. procedure TCustomListView.WndProc(var Message: TMessage);
  54. begin
  55. if not (csDesigning in ComponentState) and ((Message.Msg = WM_LBUTTONDOWN) or
  56. (Message.Msg = WM_LBUTTONDBLCLK)) and not Dragging and (DragMode = dmAutomatic) then
  57. begin
  58. if not IsControlMouseMsg(TWMMouse(Message)) then
  59. begin
  60. ControlState := ControlState + [csLButtonDown];
  61. Dispatch(Message);
  62. end;
  63. end
  64. else if not (((Message.Msg = WM_PAINT) or (Message.Msg = WM_ERASEBKGND)) and
  65. Items.FNoRedraw) then
  66. inherited WndProc(Message);
  67. end;
  68.  
  69. procedure TCoolBar.PaintWindow(DC: HDC);
  70. begin
  71. Perform(WM_ERASEBKGND, DC, );
  72. inherited;
  73. end;

总结:其实做的事情不多,子类要么就是发WM_ERASEBKGND消息给父类,要么就是改变它的消息值(使它变成另外一个消息),而父控件做的事情也很少,最主要给控件上背景色,还有就是阻止它进一步传递。

做实验:

1. 窗体上放一个覆盖了WM_ERASEBKGND消息的控件,比如TButton

2. 放一个不覆盖WM_ERASEBKGND消息的空间,比如TPanel,看看到底会出什么事情

备注:其实这种消息很难调试,只能全部记录在日志里。

WM_ERASEBKGND官方解释(翻译),以及Delphi里所有的使用情况(就是绘制窗口控件背景色,并阻止进一步传递消息)的更多相关文章

  1. Delphi 查找标题已知的窗口句柄,遍历窗口控件句柄(转)

    用我的方法来控制其他程序窗体上的窗口控件,必须先了解什么是 回调函数.我的理解是这样的: 回 调函数写出来不是自己的程序去调用的,反而是让其他的东西去调用,比如windows操作系统,比如其他的程序等 ...

  2. Delphi 查找标题已知的窗口句柄,遍历窗口控件句柄

    有了回调函数的概念及上面的例子,我们可以继续了.其实想要找到一个标题已知的窗口句柄,用一个API函数就可以了:FindWindow.其函数原形是:function FindWindow(lpClass ...

  3. Delphi中如何控制其他程序窗体上的窗口控件

    回调函数一般是按照调用者的要求定义好参数和返回值的类型,你向调用者提供你的回调函数的入口地址,然后调用者有什么事件发生的时候就可以随时按照你提供的地址调用这个函数通知你,并按照预先规定好的形式传递参数 ...

  4. Windows窗口样式速查参考,Delphi窗口控件的风格都有它们来决定(附Delphi何时用到它们,并举例说明)good

    /* 窗口样式参考列表(都是GetWindowLong的GWL_STYLE风格,都是TCreateParams.Sytle的一部分),详细列表如下:https://msdn.microsoft.com ...

  5. Delphi 操作Flash D7~XE10都有 导入Activex控件 shockwave

    http://www.cnblogs.com/devcjq/articles/2906224.html Flash是Macromedia公司出品的,用在互联网上动态的.可互动的shockwave.它的 ...

  6. Delphi第三方组件安装DCU.PAS.DPK.BPL.ActiveX控件

    不是由BORLAND提供的组件叫第三方组件:安装方法:南山古桃(nsgtao)首先提醒一下:最好把要安装的文件先复制到Delphi安装目录的Lib目录下再执行下面的操作!就目前常见的各种形式的组件的安 ...

  7. delphi 窗体透明详解TransparentColorValue,窗体透明控件不透明

    关于窗体透明的做法 来自:http://blog.csdn.net/shuaihj/article/details/8610343 关于窗体透明的做法 1.在Delphi中,设置窗体的AlphaBle ...

  8. Windows的自带控件(比如TButton)大多数消息都由它自己处理,Delphi覆盖了那么多WM_函数优先级较低,一般用不上

    在空窗体上放一个TButton,一个TPanel,然后把在TWinControl.WMEraseBkgnd里下断点: procedure TWinControl.WMEraseBkgnd(var Me ...

  9. DELPHI XE5 FOR ANDROID 模仿驾考宝典 TMEMO 控件随着字数增多自动增高

    在一个安卓需求中,需要模仿驾考宝典的详解部分.琢磨了好几天.终于搞定: MemoAns.Height:=10;//MEMO控件赋初始高度值 MemoAns.Lines.Clear; MemoAns.W ...

随机推荐

  1. javascript每日一练(九)——运动一:匀速运动

    一.js的运动 匀速运动 清除定时器 开启定时器 运动是否完成:a.运动完成,清除定时器:b.运动未完成继续 匀速运动停止条件:距离足够近  Math.abs(当然距离-目标距离) < 最小运动 ...

  2. MAMP:在 OSX 中搭建 Apache, MySQL, PHP 环境并本地安装、调试 WordPress

    MAMP 这个名字来源于 Macintosh Apache MySQL PHP,显然专门用来在 Mac 环境下搭建 Apache.MySQL.PHP 平台. 虽然 OSX 中已经预装了 Apache ...

  3. Swift - 网络请求报App Transport Security has blocked a cleartext错

    使用Xcode7编写iOS9应用时,如果获取http://数据时会报如下错误: App Transport Security has blocked a cleartext HTTP (http:// ...

  4. android 逆向project smail 语法学习

    众所周知,android 是开源的.如今市场上反编译别人的劳动果实的人也不少.所以我们也是有必要学习下smail语言,(就是androidproject反编译后出的语法语音),看看改怎么给我们的代码 ...

  5. css图片上下垂直居中

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. 超详细SDK Hello World

    Windows应用程序的基本运行机制与HelloWin程序详细解 总的来说最基本的Windows应用程序的运行执行顺序总是以如下的基本顺序执行的. 顺序结构: 调用WinMain函数开始执行--à定义 ...

  7. 用c++开发基于tcp协议的文件上传功能

    用c++开发基于tcp协议的文件上传功能 2005我正在一家游戏公司做程序员,当时一直在看<Windows网络编程> 这本书,把里面提到的每种IO模型都试了一次,强烈推荐学习网络编程的同学 ...

  8. 基于visual Studio2013解决C语言竞赛题之1018数组求和

         题目 解决代码及点评 /************************************************************************/ ...

  9. 京JS 2013 - A two-day conference in Beijing for the JavaScript and Node.js community

    京JS 2013 - A two-day conference in Beijing for the JavaScript and Node.js community 关于技术大会 京JS 2013 ...

  10. /bin/bash^M: 坏的解释器: 没有那个文件或目录

    在Linux下编译cocos2d-x运行脚本的时候出现”/bin/bash^M: 坏的解释器: 没有那个文件或目录“这样的错误如下图. 解决方法: 使用在终端输入sed -i 's/\r$//' ma ...