请问在delphi中是否可以将字体或窗口翻转(就是镜子中看到的那种)(200分)

  • 主题发起人 主题发起人 老莫
  • 开始时间 开始时间

老莫

Unregistered / Unconfirmed
GUEST, unregistred user!
小弟需要在delphi中实现反转窗口中一段文本的功能,苦无良策,希望各位专<br>家能够指教。是否能够通过调用win32 API使窗口或字体翻转,如果有别的方法<br>也可以。<br>
 
使用位图操作吧。
 
多谢tqz指教,但小弟的这段文本是需要从文件中读取刷新的,文件比较大,需要滚屏<br>操作,用位图可能不行。<br>
 
请你看看VC的在线帮助:LOGFONG结构:里面有一个LONG lfEscapement的属性:<br>lfEscapement &nbsp; Specifies the angle, in tenths of degrees, of each line of text written in the font (relative to the bottom of the page).<br>创建字体是设计这些性质,我想就可以了。<br>
 
&lt;pre&gt;&lt;font size=3&gt;<br>使用LMD控件组中的LMDLabelFill控件,可设置FontFx.Angle属性,设<br>置label的旋转角度属性,设置为180,即可出来您所要求的效果,<br>LMD3.5,LMD4.0都有这个控件,在许多控件组的LABEL控件都有类似<br>功能。<br>&lt;/font&gt;&lt;/pre&gt;<br>
 
翻转不是旋转!<br>我看你是要打印胶片之类的,只能对pixel操作了!<br>你可以先把文本读出来生成bmp然后随时对显示的<br>部分的相素移位.
 
sorry!理解错了
 
我不太清楚你最终想得到什么结果,如果是想得到图象,那肯定要使用位图操作;<br>基本方法就是ZX的方法。
 
举个翻转TLabel的例子,其实TMemo也一样,只是对TWincontrol而言,涉及光标<br>的计算,要复杂一些.其实我的例子可适合一切基于TGraphicControl的控件,<br>即使有滚动区哉也不要紧,难道你还要求看不见的部分也翻转?<br><br>unit RevLabels;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br>&nbsp; StdCtrls;<br><br>type<br>&nbsp; TRevLabel = class(TLabel)<br>&nbsp; protected<br>&nbsp; &nbsp; procedure Paint; override;<br>&nbsp; end;<br><br>procedure Register;<br><br>implementation<br><br>procedure Register;<br>begin<br>&nbsp; RegisterComponents('Samples', [TRevLabel]);<br>end;<br><br>procedure TRevLabel.Paint;<br>var<br>&nbsp; I, J: Integer;<br>&nbsp; AColor: TColor;<br>begin<br>&nbsp; inherited Paint;<br>&nbsp; with Canvas do<br>&nbsp; &nbsp; for I := 0 to (ClientRect.Right - ClientRect.Left - 1) div 2 do<br>&nbsp; &nbsp; &nbsp; for J := ClientRect.Top to ClientRect.Bottom do<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; AColor := Pixels[ClientRect.Left + I, J];<br>&nbsp; &nbsp; &nbsp; &nbsp; Pixels[ClientRect.Left + I, J] := Pixels[ClientRect.Right - I - 1, J];<br>&nbsp; &nbsp; &nbsp; &nbsp; Pixels[ClientRect.Right - I - 1, J] := AColor;<br>&nbsp; &nbsp; &nbsp; end;<br>end;<br><br>end.
 
用vga的dac和直接改写vram可也!<br>
 
多谢各位前辈指教<br>barton提供的方法我试了一下,刷新速度较慢,另外我用的memo部件也不支持<br>canvas属性。其实,小弟做的这个东西是需要使用者对其进行滚屏操作的,对平<br>滑性有较高的要求。<br>lss的想法我以前也试过,但做出的效果是平面旋转180度。<br>如果能够创建一种翻转的字体就好了,或者索性把字库翻转,或者对窗口操作,将<br>窗口中所有的内容都翻转。<br>
 
还是建议你用位图操作,这样编程比较方便,而且速度快些。<br>取得Memo.Handle,然后bitblt到一个内存位图上,然后翻转(建议用Scanline<br>比较快,但是要注意不同格式的位图Scanline也不一样),然后显示到Form的Canvas<br>上。
 
格式不是问题, 只要指定bitmap的pixelformat即可(bitblt之后设置, 不然可能会出现奇怪的图象, 我的经验)
 
我也建议你研究一下truetype,这应该是最便捷的方法了。
 
tqz兄能不能讲得详细一点,小弟对你讲的内容不太熟悉。
 
我给个小例子吧。老实说跟barton的可能差不多,不过用DoubleBuffer和Scanline<br>以提高性能。等我吃完饭回来再写...
 
直接获取屏幕,截取你要的部分再处理,这样就无所谓什么控件没有canvas了<br>关于截屏的procedure已经很多,我就不贴出来了<br>另外如果翻转是固定沿着某方向,可以以行(列)为单位处理:推荐 bitblt<br>同时以DoubleBuffer处理速度是相当快的<br><br>
 
sorry,今晚还耽误了些时间,下面稍微改了一些Barton的code:<br>procedure TRevLabel.Paint;<br>var &nbsp;I, J: Integer; &nbsp;AColor: TColor;<br>Temp:array[1..3] of Byte;<br>begin<br>&nbsp; inherited Paint;<br>&nbsp; if MemBitmap.Width&lt;&gt;Width then<br>&nbsp; &nbsp; MemBitmap.Width:=Width;<br>&nbsp; if MemBitmap.Height&lt;&gt;Height then<br>&nbsp; &nbsp; MemBitmap.Height:=Height;<br>&nbsp; MemBitmap.Canvas.CopyRect(ClientRect,Canvas,ClientRect);<br>&nbsp; for i:=0 to MemBitmap.Height-1 do<br>&nbsp; &nbsp; for j := 0 to (MemBitmap.Width - 1) div 2 do<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; Move(PByteArray(MemBitmap.ScanLine)[j*3],Temp[1],3);<br>&nbsp; &nbsp; &nbsp; Move(PByteArray(MemBitmap.ScanLine)[(Width-j-1)*3],PByteArray(MemBitmap.ScanLine)[j*3],3);<br>&nbsp; &nbsp; &nbsp; Move(Temp[1],PByteArray(MemBitmap.ScanLine)[(Width-j-1)*3],3);<br>&nbsp; &nbsp; end;<br>&nbsp; Canvas.CopyRect(ClientRect,MemBitmap.Canvas,ClientRect);<br>end;<br>比它的显示快一些。问题还是要闪烁,因为老的Paint已经画到Screen上了<br>TCustomLabel的Code中在DoDrawText里面是直接画到屏幕的,要改就得继承<br>DoDrawText,问题是继承后引起很多相关问题...:(如果对目前效果还满意的话<br>就凑合用吧。
 
基本照抄 tqz, 不过没闪烁:<br><br>procedure TRevLabel.Paint;<br>var &nbsp;I, J: Integer; &nbsp;AColor: TColor;<br>Temp:array[1..3] of Byte;<br>begin<br>&nbsp; if csPaintCopy in Controlstate then<br>&nbsp; begin<br>&nbsp; &nbsp; inherited Paint;<br>&nbsp; &nbsp; exit;<br>&nbsp; end<br>&nbsp; else begin<br>&nbsp; &nbsp; if MemBitmap.Width&lt;&gt;Width then<br>&nbsp; &nbsp; &nbsp; MemBitmap.Width:=Width;<br>&nbsp; &nbsp; if MemBitmap.Height&lt;&gt;Height then<br>&nbsp; &nbsp; &nbsp; MemBitmap.Height:=Height;<br>&nbsp; &nbsp; Self.PaintTo(membitmap.Canvas.Handle, 0, 0);<br>&nbsp; &nbsp; for i:=0 to MemBitmap.Height-1 do<br>&nbsp; &nbsp; &nbsp; for j := 0 to (MemBitmap.Width - 1) div 2 do<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; Move(PByteArray(MemBitmap.ScanLine)[j*3],Temp[1],3);<br>&nbsp; &nbsp; &nbsp; &nbsp; Move(PByteArray(MemBitmap.ScanLine)[(Width-j-1)*3],PByteArray(MemBi &nbsp;tmap.ScanLine)[j*3],3);<br>&nbsp; &nbsp; &nbsp; &nbsp; Move(Temp[1],PByteArray(MemBitmap.ScanLine)[(Width-j-1)*3],3);<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; Canvas.CopyRect(ClientRect,MemBitmap.Canvas,ClientRect);<br>&nbsp; end;<br>end;
 
另一只眼兄,你的方法恐怕不行,因为paintTo是TWinControl的方法,而TLabel 继<br>承自TGraphicControl.如果从 TStaticText继承就可以了。<br>另外,在TCustomLabel.AdjustBounds中,有:<br>&nbsp; &nbsp; DC := GetDC(0);<br>&nbsp; &nbsp; Canvas.Handle := DC;<br>&nbsp; &nbsp; DoDrawText(Rect, (DT_EXPANDTABS or DT_CALCRECT) or WordWraps[FWordWrap]);<br>&nbsp; &nbsp; Canvas.Handle := 0;<br>&nbsp; &nbsp; ReleaseDC(0, DC);<br>直接在屏幕的DC上写,所以可以继承DoDrawText,或者彻底修改AdjustBounds,<br>否则无法避免闪烁。
 
后退
顶部