分享

PB 小技巧

 冰冻三尺roy 2010-09-14

1,怎样得到下拉数据窗显示列的值
下面的代码使用了Describe()的Evaluate()函数,其功能是得到state_code列的显示值,该列使用了下拉数据窗口(DropDownDataWindow)编辑风格。这段代码应该在发生过ItemChanged事件后执行,这样用户所选值已经被放入了相应的缓冲区。为了安全,下面的代码放置在名称为getdisplayvalue的数据窗口用户自定义事件中:
string rownumber, displayvalue
rownumber = String(dw_1.GetRow())
displayvalue = dw_1.Describe( "Evaluate('LookUpDisplay(state_code) ', " &
+ rownumber + ")")
dw_1.Describe("Evaluate('LookUpDisplay(columnname)',"+String(this.GetRow())+")"))
2,在PB下实现多边形的窗口 

看了如烟网友《如何在PB下实现圆形窗口》的文章,用了一下不错,希望也能写一些东西对大家有所帮助!

如下:

首先在窗口定义下列局部外部函数(Local External Functions...):

Function ulong CreatePolygonRgn (ref tagPOINT lppt[], int cPoints, int fnPolyFillMode ) Library "gdi32.dll"

FUNCTION ulong SetWindowRgn(ulong hWnd,ulong hRgn,boolean bRedraw) LIBRARY "user32.dll"

在窗口上定义

Structure

tagpoint

{ long x 
long y}

在窗口的open事件中加上:

long hrgn
long lres
tagPOINT l_pointapi[]


l_pointapi[1].x = 173 
l_pointapi[1].y = 112

l_pointapi[2].x = 412 
l_pointapi[2].y = 66

l_pointapi[3].x = 478 
l_pointapi[3].y = 240

l_pointapi[4].x = 338 
l_pointapi[4].y = 340 //多边形各个顶点坐标值

hrgn = CreatePolygonRgn(l_pointapi[],4,1)
//其中第 1 个参数为多边形各个顶点坐标值的数组
//其中第 2 个参数为多边形边数,可修改,配合数组值
//其中第 3 个参数为填充模式 ALTERNATE /WINDING 
lres=setwindowRgn(handle(this),hrgn,true)
设置了填充模式,但看不出来,不知到底有什么用,望大虾们告知

 
3,PB的状态条很难看,不能增加更多的分割条,字体也很难看,有什么办法可以改善? 


PB状态栏并不是一个控件,它是一个属于MDI主窗口的子窗口(child window)

在6.0中其类名为"FNHELP60",由此可查到状态栏的句柄,下面的程序段将句柄取出并保存在llhStatusBar变量中
// Win32 API 
function long FindWindowA( String lpClassName, String lpWindowName ) Library "user32"
function long FindWindowExA( long hParent, long hChildAfter, String lpszClass, String lpszWindow ) Library "user32"

//Open event script in the frameWindow
long llNULL, llhStatusBar
string lsClassName, lsWindowName
Environment lEnv

// Check the FrameWindow is a valid window, and get current environment settings
IF IsValid( this ) AND (GetEnvironment(lEnv) = 1) THEN

// Check that this an MDI frame window with a standard statusbar
IF (this.WindowType = MDIHelp!) THEN

// Set classname of statusbar based on PB version
CHOOSE CASE lEnv.PBMajorRevision
CASE 5
lsClassName = "FNHELP050"
CASE 6
lsClassName = "FNHELP60"
// Add code here for PB4 and PB7
END CHOOSE

// Get handle to statusbar
SetNull(lsWindowName)
SetNull(llNULL)
llhStatusBar = FindWindowEXA( Handle(this), llNULL, lsClassName, lsWindowName )
END IF
END IF


但是我想引用这个子窗口的名字,
以便把它分成多列!有办法吗?


得到微帮助的句柄以后,还有什么是不能做的呢?你可以用TextOut在微帮助条上输出字符,当然在此之前,你还可以用CreateFont设定字体, 用SetBkColor和 SetTextColor设定颜色.如果你想加入分割线可以用MoveToEx加LineTo,不过这样一来就比较麻烦了.^_^
//Win 32 API
Function ulong CreateFont (int nHeight, int nWidth, int nEscapement, int nOrientation, int nWeight, ulong fbItalic, ulong fbUnderline, ulong fbStrikeOut, ulong fbCharSet, ulong fbOutputPrecision, ulong fbClipPrecision, ulong fbQuality, ulong fbPitchAndFamily, ref string lpszFace) ALIAS FOR "CreateFontA" Library "GDI32.DLL"
Function ulong GetDC (ulong hWnd) Library "USER32.DLL"
Function ulong SetBkColor (ulong hDC, ulong crColor) Library "GDI32.DLL"
Function ulong SetTextColor (ulong hDC, ulong crColor) Library "GDI32.DLL"
Function boolean TextOut (ulong hdcr, integer stx, integer sty, ref string lpString, long nCount) Library "GDI32.DLL" Alias for "TextOutA"
Function boolean LineTo (ulong hDC, integer wx, integer wy) Library "GDI32.DLL"
Function boolean MoveToEx (ulong hDC, int x, int y, ref tagPoint lppt ) Library "GDI32.DLL"
Function ulong SelectObject (ulong hDC, ulong hWnd) Library "GDI32.dll"

//Open event script
string  ls_facename = "宋体"
ilh_statusbarhdc = GetDC(llhStatusBar)

ll_Font = CreateFont(16, 0, 0, 0, 400, 0, 0, 0, 255, 0, 0, 0, 18, ls_facename)
SelectObject (ilh_statusbarhdc, ll_font) 
SetBkColor (ilh_statusbarhdc, rgb( 0,0,165 ))
SetTextColor (ilh_statusbarhdc, rgb( 0,165,0 ))

自定义一个事件ue_paint,选择pbm_paint,在其中添加字符串输出:
string ls_facename = "呵呵!一切就绪"
TextOut ( ilh_statusbarhdc, 100, 3, ls_facename, len( ls_facename ))

 

为PB的微帮助条加分割线:
首先tagPoint 是一个结构,你需要先在PB中声明之:
type str_pos from structure
long x
long y
end type
//win32 API
Function ulong GetDC(ulong hwnd) library "user32.dll"
FUNCTION boolean MoveToEx(ulong hwnd,long wx, long wy,ref str_pos prepos2) LIBRARY "Gdi32.dll"
FUNCTION boolean LineTo(ulong hwnd,long wx, long wy) LIBRARY "Gdi32.dll"
Function ulong CreatePen (uint nPenStyle, uint nWidth, ulong crColor) Library "GDI32.DLL"
Function ulong SelectObject (ulong hDC, ulong hWnd) Library "GDI32.dll"

//Open event script
// llhStatusBar是微帮助条窗口句柄
ilh_statusbarhdc = GetDC(llhStatusBar) //如何取微帮助条窗口句柄,见595贴
//用CreatePen建立画线的线形,这里为红线,1个像素宽
SelectObject (ilh_statusbarhdc, CreatePen ( 0, 1, rgb( 255,0, 0 ) ) )

//在ue_paint事件中画分割线,线的起点在98,3,终点在98,18(单位: 像素)
str_pos strvar

MoveToEx(ilh_statusbarhdc, 98, 3, strvar)
Lineto( ilh_statusbarhdc, 98, 18 )

4,以动画效果打开你的Window


下面的函数只能用于Windows 98/2000平台

可以为您的程序增加很Cool的Splash画面(或者您需要的Window)
在您的程序中定义外部函数
Function boolean AnimateWindow( &   long lhWnd, long lTm, long lFlags ) library 'user32' 
注:以上第一个参数是您的Windows的句柄,使用handle(w_1)即可获得,第二个参数是需要的动画效果。第三个参数是动画类型

再将下面代码放入到您的窗口open事件中

// Animate the window from left to right
Constant Long AW_HOR_POSITIVE = 1
// Animate the window from right to left
Constant Long AW_HOR_NEGATIVE = 2 
// Animate the window from top to bottom
Constant Long AW_VER_POSITIVE = 4 
// Animate the window from bottom to
Constant Long AW_VER_NEGATIVE = 8
// Makes the window appear to collapse inward
Constant Long AW_CENTER = 16
// Hides the window
Constant Long AW_HIDE = 65536
// Activates the window
Constant Long AW_ACTIVATE = 131072
// Uses slide animation
Constant Long AW_SLIDE = 262144
// Uses a fade effect
Constant Long AW_BLEND = 524288

AnimateWindow( Handle( this ), 500, AW_VER_NEGATIVE )可以下载更完整的PB例程和演示效果,由ilike提供
hWnd:指定产生动画的窗口的句柄。 
dwTime:指明动画持续的时间(以微秒计),完成一个动画的标准时间为200微秒。 
dwFags:指定动画类型。这个参数可以是一个或多个下列标志的组合。标志描述:

AW_SLIDE:使用滑动类型。缺省则为滚动动画类型。当使用AW_CENTER标志时,这个标志就被忽略。 
AW_ACTIVATE:激活窗口。在使用了AW_HIDE标志后不能使用这个标志。 
AW_BLEND:实现淡出效果。只有当hWnd为顶层窗口的时候才可以使用此标志。 
AW_HIDE:隐藏窗口,缺省则显示窗口。 65536
AW_CENTER:若使用了AW_HIDE标志,则使窗口向内重叠,即收缩窗口;若未使用AW_HIDE标志,则使窗口向外扩展,即展开窗口。 
AW_HOR_POSITIVE:自左向右显示窗口。该标志可以在滚动动画和滑动动画中使用。当使用AW_CENTER标志时,该标志将被忽略。 
AW_VER_POSITIVE:自顶向下显示窗口。该标志可以在滚动动画和滑动动画中使用。当使用AW_CENTER标志时,该标志将被忽略。 
AW_VER_NEGATIVE:自下向上显示窗口。该标志可以在滚动动画和滑动动画中使用。当使用AW_CENTER标志时,该标志将被忽略。

返回值:如果函数成功,返回值为非零;如果函数失败,返回值为零。在下列情况下函数将失败:

窗口使用了窗口边界;窗口已经可见仍要显示窗口;窗口已经隐藏仍要隐藏窗口。
5,判断一个应用是否正在运行
定义一个全局外部函数:
FUNCTION ulong FindWindowA(ulong classname,string windowname) LIBRARY "user32.dll"

Application的Open事件中的代码:

boolean rtn
ulong l_handle, lu_class
string ls_name
setnull(lu_class)
ls_name = "API Name" // 将API Name换了你的主窗口的标题title
l_handle = FindWindowA(lu_class, ls_name)
if l_handle > 0 then
MessageBox("应用程序多次运行", This.AppName + "已经运行,你不能多次启动!")
Halt Close
else
open(w_main)
end if
6,打开任意注册后类型的文件(用API)
ShellExecute

VB声明 
Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long 
说明 
查找与指定文件关联在一起的程序的文件名。关联的方式要么是运行程序,要么是打印文件。可用Windows注册表编辑器将特定的文件类型同应用程序关联起来。例如,扩展名为.TXT的文本文件通常与Windows记事本(NOTEPAD.EXE)关联到一起。如在文件管理器中双击含.TXT扩展名的一个文件,就会自行启动记事本程序,并在其中载入文本文件;或者将指定的文件打印出来 
返回值 
Long,大于32表示成功。请参考对FindExecutable函数的说明,了解具体的错误代码列表 
参数表 
参数 类型及说明 
hwnd Long,指定一个窗口的句柄,有些时候,Windows程序有必要在创建自己的主窗口前显示一个消息框。如果发生这种情况,由这个参数指定的窗口就会作为消息框的父窗口使用。在VB环境中,通常将活动窗体的窗口句柄作为这个参数使用 
lpOperation String,指定字串“Open”来打开lpFlie文档;或指定“Print”来打印它。也可设为vbNullString,表示默认为“Open” 
lpFile String,想用关联的程序打印或打开的一个程序名或文件名 
lpParameters String,如lpFile是一个可执行文件,则这个字串包含了传递给执行程序的参数。如lpFile引用的是一个文档文件,或者不需要使用参数,则设为vbNullString 
lpDirectory String,想使用的默认路径完整路径 
nShowCmd Long,定义了如何显示启动程序的常数值。参考ShowWindow函数的nCmdShow参数

用Run函数
Run("???.???  !!!.!!!")?为类型文件打开的程序,!为要打开的文件名,例如:Run(Winrar.Exe  Abc.Zip)用Winrar打开Abc.Zip文件

用ShellExecute
声明:
FUNCTION ulong ShellExecute(ulong hwnd,ref string lpOperation,ref string lpFile,ref string lpParameters,ref string lpDirectory,ulong nShowCmd) LIBRARY "shell32.dll" ALIAS FOR "ShellExecuteA"

调用:
ShellExecute(Handle(Parent),str_null,pathname,str_null,str_null,1)

注:
str_null:字符型变量,不需赋值,声明即可
pathname:要打开的文件名(包括完整路径)

 


7,实现鼠标左键按住窗体就可以移动窗体
窗体上面有Picture的处理方法
把 Picture 设为 Enabled = False
仍在窗口的 MouseDown 中写代码:
 Send ( Handle ( This ), 274, 61458, 0 )

8,PB制作进度条
PowerBuilder  是大家公认的、  最佳的数据库前端开发工具之一,但一直以来,PB在用户界面的处理上十分单调,最明显的例子是,所有的窗口控件都不支持透明色即transparent  。PowerBuilder  7以前的版本没有提供进度条,造成大多数程序员总是自己在程序中利用两个矩形控件(Rectangle)进行编程产生进度效果。但是这样一来,进度条中的进度百分比就没有了,如果再加上一个静态文本作为百分比显示,由于statictext控件没有透明色,进度条的百分比显示无法与进度条进行重叠,只得在进度条外的其它位置放置一statictext控件用以显示进度情况,这样即浪费了空间,又不美观。    
 
在网上也曾看到过解决的方法,主要是利用了数据窗口中控件可以透明处理的特征,但总感觉美中不足,数据窗口是一种重型控件,要占用大量的系统资源,能不能用其他更简单的方法解决上述问题呢?    
 
上述问题的关键在于文本的输出背景要透明,我们知道:Windows系统本身提供了大量的底层API功能函数供上层的应用程序调用,文本的输出该是最基本的吧,所以Windows一定能够解决文本背景透明输出的问题。仔细查找API帮助,果然找到相关的函数,于是问题迎刃而解。    
 
下面列出主要的声明和对象实现的主要程序段:    
 
新建一可视定制用户对象uo_progressbar,在其中放置两个矩形控件(Rectangle),分别命名为:r_back  和  r_front。定义实例变量如下:    
 
ulong  iul_ihDC  //保存可视定制用户对象的DC句柄    
real  ir_step  //根据对象宽度计算出来的步进值    
integer  ii_x,  ii_y    
//根据对象宽度和高度计算出来的文本输出位置    
 
声明Local  external  functions如下:    
 
Function  ulong  GetDC  (ulong  hWnd)  Library  "USER32.DLL"    
 
Function  boolean  TextOut  (ulong  hdcr,  integer  stx,    
integer  sty,  ref  string  lpString,  long  nCount)    
Library  "GDI32.DLL"  Alias  for  "TextOutA"    
 
Function  int  SetBkMode  (ulong  hdcr,  integer  mode)    
Library  "GDI32.DLL"    
 
在对象的constructor事件中输入以下代码:    
 
integer  li_width,  li_height    
//根据对象变框计算宽高    
CHOOSE  CASE  this.BorderStyle    
CASE  StyleLowered!,StyleRaised!    
li_width  =  this.width  -  PixelsToUnits(4,  XPixelsToUnits!)    
li_height  =  this.height  -  PixelsToUnits(4,  YPixelsToUnits!)    
CASE  StyleBox!,StyleShadowBox!    
li_width  =  this.width  -  PixelsToUnits(2,  XPixelsToUnits!)    
li_height  =  this.height  -  PixelsToUnits(2,  XPixelsToUnits!)    
CASE  Else    
li_width  =  this.width    
li_height  =  this.height    
END  CHOOSE    
 
r_back.width  =  li_width    
r_front.height  =  li_height    
r_front.width  =  0    
r_back.height  =  li_height    
//计算百分比文本输出的位置使其在水平和垂直方向上居中    
ii_x  =  UnitsToPixels(li_width,  XUnitsToPixels!)/2  -  16    
ii_y  =  (  UnitsToPixels(li_height,  YUnitsToPixels!)  -  16  )/2    
ir_step  =  li_width/100  //计算步进值    
iul_ihDC  =  GetDC(  handle(this)  )    
//获得对象DC句柄,用于API调用    
SetBkMode  (iul_ihdc,  1  )  //设置文本输出背景色透明    
 
return  0    
为对象写一个函数:of_setposition,    
//功能:根据参数改变进度显示    
//参数:integer  ai_percent    
//返回:无    
string  ls_msg    
integer  li_x    
If  ai_percent  <=  100  and  ai_percent  <  0  then  SetRedraw(FALSE)  li_x="ai_percent*ir_step"  r_back.x="li_x"  r_front.width="li_x"  ls_msg="string("  ai_percent  )+"%"  SetRedraw(True)  TextOut  (iul_ihdc,  ii_x,  ii_y,  ls_msg,  len(  ls_msg  )  )  End  If    
 
当然你还可以编写函数改变进度条中的前景色背景色和文本颜色,这里不再赘述。

9,Datawindow中每页打印固定行
(深圳:独孤求败 2003-05-19) 
第一步: 
增加一个计算列,此计算列必须放在Detail段,Expression中输入:ceiling(getrow()/20),这里20还可以用全局函数取代,这样可以允许用户任意设置每页打印多少行。 
第二步: 
定义分组,选择菜单Rows->Create Group...按计算列字段分组,并一定将check box-->New Page On Group Break选中。
第三步: 
将此计算列设为不可视。另外,如果需要最后一页不足补空行。也很简单,如下:
long ll_pagerow = 6 //每页打印行数
long ll_count, ll_row
ll_count = dw_report.retrieve(...) //取得现有报表的总行数
ll_count = ll_pagerow - mod(ll_count, ll_pagerow)
If ll_count < ll_pagerow Then
   for ll_row = 1 to ll_count 
       dw_print.insertrow(0) //补足空行
   next
end If


10,sql语句将行转换成列

declare @sql varchar(8000) 
set @sql = 'select 物料代码' 
select @sql = @sql + ',sum(case 地区 when '''+地区+''' then 数量 end) ['+地区+']' 
   + ',sum(case 地区 when '''+地区+''' then 比率 end) [比率]' 
from (select distinct 地区 from 表) as a 
select @sql = @sql+' from 表 group by 物料代码' 
exec(@sql)
简化如下:
select (select 物料代码 ,
sum(case 地区 when '地区' then 数量 end)[地区],
sum(case 地区 when '地区' then 比率 end)[比率]

from (select distinct 地区 from 表) as a
)
from 表 group by 物料代码

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约