如何在DW中设置自动列宽

如何在DW中设置自动列宽
作者 华软 raymen
看到《如何在DW中设置自动列宽》,从我的类库中扣了一段代码回复了,后来又从旧硬盘中找到原来老外写的对象,上传给大家吧

$PBExportHeader$n_dwautowidth.sru
$PBExportComments$Performs autowidth on grid datawindow columns
forward
global type n_dwautowidth from nonvisualobject
end type
end forward
type os_size from structure
long cx
long cy
end type
global type n_dwautowidth from nonvisualobject autoinstantiate
end type
type prototypes
Function ulong GetDC(ulong hWnd) Library "user32.dll"
Function ulong SelectObject(ulong hdc, ulong hWnd) Library "gdi32.dll"
Function boolean GetTextExtentPoint32A(ulong hdcr, string lpString, long nCount, ref os_size size) Library "gdi32.dll"
Function long ReleaseDC(ulong hWnd, ulong hdcr) Library "user32.dll"
end prototypes
type variables
Constant Integer WM_GETFONT = 49
Window iw_parent
Datawindow idw_data
Integer ii_original[]
end variables
forward prototypes
public subroutine of_register (readonly window aw_parent, ref datawindow adw_datawindow)
public function long of_resize (string as_colname)
public function long of_resize (integer ai_colnbr)
end prototypes
public subroutine of_register (readonly window aw_parent, ref datawindow adw_datawindow);// -----------------------------------------------------------------------------
// SCRIPT: n_dwautowidth.of_register
//
// PURPOSE: This function saves a reference to the window and datawindow
// in instance variables for use in the of_resize function. It
// also saves the initial width of all visible columns to use as
// minimum width.
//
// CALLED BY: Usually called from Constructor event of the datawindow or right
// after setting the .DataObject property of the dw control.
//
// ARGUMENTS: aw_parent - Window that the datawindow is on
// adw_datawindow - Datawindow whose columns will be resized
//
// RETURN: Row containing the longest value
//
// DATE PROG/ID DESCRIPTION OF CHANGE / REASON
// ---------- ---------- -----------------------------------------------------
// 11/25/2002 Roland S Initial creation
// -----------------------------------------------------------------------------
Integer li_col, li_max
// save references to parent window and datawindow
iw_parent = aw_parent
idw_data = adw_datawindow
// record column original size
li_max = Integer(adw_datawindow.Object.DataWindow.Column.Count)
FOR li_col = 1 TO li_max
ii_original[li_col] = Integer(adw_datawindow.Describe("#" + String(li_col) + ".Width"))
NEXT
end subroutine
public function long of_resize (string as_colname);// -----------------------------------------------------------------------------
// SCRIPT: n_dwautowidth.of_resize
//
// PURPOSE: This function will change the column width so that the longest
// value will fit. The minimum width is the initial width set in
// the datawindow painter.
//
// CALLED BY: Usually called from RetrieveEnd event of the datawindow or
// just after inserting/modifying the values in the column.
//
// ARGUMENTS: as_colname - Column to be resized
//
// RETURN: Row containing the longest value
//
// DATE PROG/ID DESCRIPTION OF CHANGE / REASON
// ---------- ---------- -----------------------------------------------------
// 11/25/2002 Roland S Initial creation
// -----------------------------------------------------------------------------
Long ll_row, ll_max, ll_maxrow
ULong lul_Handle, lul_hDC, lul_hFont
Integer li_maxwidth, li_rc, li_size, li_colnbr
String ls_value, ls_format, ls_modify
StaticText lst_text
os_size lstr_Size
li_rc = iw_parent.OpenUserObject(lst_text)
If li_rc = 1 Then
// get column number
li_colnbr = Integer(idw_data.Describe(as_colname + ".ID"))
// get column format string
ls_format = idw_data.Describe(as_colname + ".Format")
// give static text same font properties as column
lst_text.FaceName = idw_data.Describe(as_colname + ".Font.Face")
lst_text.TextSize = Integer(idw_data.Describe(as_colname + ".Font.Height"))
lst_text.Weight = Integer(idw_data.Describe(as_colname + ".Font.Weight"))
// set italic property
If idw_data.Describe(as_colname + ".Font.Italic") = "1" Then
lst_text.Italic = True
Else
lst_text.Italic = False
End If
// set charset property
CHOOSE CASE idw_data.Describe(as_colname + ".Font.CharSet")
CASE "0"
lst_text.FontCharSet = ANSI!
CASE "2"
lst_text.FontCharSet = Symbol!
CASE "128"
lst_text.FontCharSet = ShiftJIS!
CASE "255"
lst_text.FontCharSet = OEM!
CASE ELSE
lst_text.FontCharSet = DefaultCharSet!
END CHOOSE
// set family property
CHOOSE CASE idw_data.Describe(as_colname + ".Font.Family")
CASE "1"
lst_text.FontFamily = Roman!
CASE "2"
lst_text.FontFamily = Swiss!
CASE "3"
lst_text.FontFamily = Modern!
CASE "4"
lst_text.FontFamily = Script!
CASE "5"
lst_text.FontFamily = Decorative!
CASE ELSE
lst_text.FontFamily = AnyFont!
END CHOOSE
// set pitch property
CHOOSE CASE idw_data.Describe(as_colname + ".Font.Pitch")
CASE "1"
lst_text.FontPitch = Fixed!
CASE "2"
lst_text.FontPitch = Variable!
CASE ELSE
lst_text.FontPitch = Default!
END CHOOSE
// create device context for statictext
lul_Handle = Handle(lst_text)
lul_hDC = GetDC(lul_Handle)
// get handle to the font used by statictext
lul_hFont = Send(lul_Handle, WM_GETFONT, 0, 0)
// Select it into the device context
SelectObject(lul_hDC, lul_hFont)
// walk thru each row of datawindow
ll_max = idw_data.RowCount()
FOR ll_row = 1 TO ll_max
// get value from datawindow
ls_value = RightTrim(String(idw_data.object.data[ll_row, li_colnbr], ls_format))
// determine text width
If Not GetTextExtentPoint32A(lul_hDC, ls_value, Len(ls_value), lstr_Size) Then
ReleaseDC(lul_Handle, lul_hDC)
iw_parent.CloseUserObject(lst_text)
Return -1
End If
// convert length in pixels to PBUnits
li_size = PixelsToUnits(lstr_Size.cx, XPixelsToUnits!)
If li_size > li_maxwidth Then
li_maxwidth = li_size
ll_maxrow = ll_row
End If
NEXT
// release the device context
ReleaseDC(lul_Handle, lul_hDC)
// modify the column width
If li_maxwidth > ii_original[li_colnbr] Then
ls_modify = as_colname + ".Width = " + String(li_maxwidth + 8)
Else
ls_modify = as_colname + ".Width = " + String(ii_original[li_colnbr])
End If
idw_data.Modify(ls_modify)
// destroy statictext
iw_parent.CloseUserObject(lst_text)
End If
Return ll_maxrow
end function
public function long of_resize (integer ai_colnbr);// -----------------------------------------------------------------------------
// SCRIPT: n_dwautowidth.of_resize
//
// PURPOSE: This function gets the name for the passed column number
// and passes it to the function that does the resizing.
//
// CALLED BY: Usually called from RetrieveEnd event of the datawindow or
// just after inserting/modifying the values in the column.
//
// ARGUMENTS: ai_colnbr - Column to be resized
//
// RETURN: Row containing the longest value
//
// DATE PROG/ID DESCRIPTION OF CHANGE / REASON
// ---------- ---------- -----------------------------------------------------
// 11/25/2002 Roland S Initial creation
// -----------------------------------------------------------------------------
String ls_colname
ls_colname = idw_data.Describe("#" + String(ai_colnbr) + ".Name")
Return this.of_resize(ls_colname)
end function
on n_dwautowidth.create
TriggerEvent( this, "constructor" )
end on
on n_dwautowidth.destroy
TriggerEvent( this, "destructor" )
end on

把上面代码复制,保存为XXX.SRU,导入到自己应用中去就可以了。
调用方法

n_dwautowidth in_dwaw
in_dwaw.of_register(Parent, dw_list)
in_dwaw.of_resize("列名")

大家按需使用吧
同贴中又一兄弟提到“如果列太长,即使实现也很难看。。”,深以为然,在此也提供一个方案供参考。
上面的对象修改一下,如果of_gettextsize得到的值太大(自己定义这个值吧),则不修改列宽。在DW的MOUSEMOVE事件:

if ib_autotips then 
String ls_dwo,ls_col,ls_text
long ll_row
int li_pos
ls_dwo=GetObjectAtPointer()
if is_prior_dwo = ls_dwo then 
return
else
is_prior_dwo = ls_dwo
end if
if inv_tips.tipvisible() then inv_tips.hidetip(this)
li_pos= Pos(ls_dwo, "~t")
if li_pos<=0 then return
ls_col = Left (ls_dwo, li_pos - 1 )
ll_row = Long(Mid(ls_dwo,li_pos + 1 ))
if Describe(ls_col+".Type")<>"column" then return//不是列对象
int ll_width,ll_needWidth,ll_x , ll_needheight
string ls_editSty
ll_width=long(describe(ls_col+".Width"))
ll_x=long(describe(ls_col+".x"))
ls_editSty =Describe(ls_col+".Edit.Style")
if ls_editSty="editmask" then //有掩码
int li_colNum
string ls_mask
li_colNum=integer(Describe(ls_col+".ID"))
ls_mask =Describe(ls_col+".EditMask.Mask")
if Left(Describe(ls_col+".Coltype"),4)="char" then //字符型掩码
//字符可以转化为数字(直接用string(s,"##")得不到)
n_cst_string inv_str
inv_str.of_globalreplace(ls_mask,"#","@")
ls_text=string(this.Object.Data[ll_row,li_colNum],ls_Mask) 
else//其它类型掩码
ls_text=string(this.Object.Data[ll_row,li_colNum],ls_Mask)
end if
else
//当前行列值(便于dddw,ddlb得到显示值)
ls_text=Describe("Evaluate('LookUpDisplay("+ls_col+")',"+String(ll_row)+")")
end if
//需要宽度
if of_gettextsize(ls_col , ls_text , ll_needheight , ll_needwidth) <> 1 then return
if ls_editSty="checkbox" or ls_editSty="radiobuttons" then 
//这两种类型需要加个额外值
ll_needWidth+=86
end if
//列的宽度不够 或者 位于显示的最右列,只能显示一部分
if ll_width<ll_needWidth or & 
ll_x+ll_width>=This.Width +long(Object.DataWindow.HorizontalScrollPosition) then
//修改Tip
inv_tips.of_addtool(this,ls_Text,0)
// inv_tips.of_settiptext(this,0,ls_text)
inv_tips.of_relaymsg(this)
return
end if
end if

好了,这样就可以完美解决问题了。
上文中ib_autotips是DW的变量,通过of_setautotips(true/false)来设定。
上文中用到的inv_tips对象好多年前就在网上泛滥了,自己找吧

猜你喜欢

转载自blog.csdn.net/tlammon/article/details/51340692