The DrawEdge API provides a convenient way to draw a number of interesting effects. You can change the EDGE_ constants to give different border effects; the BF_ constants determine which borders are drawn (for example, BF_BOTTOM):
Private Declare Function DrawEdge Lib "user32" (ByVal hDC _ As Long, qrc As RECT, ByVal edge As Long, ByVal _ grfFlags As Long) As LongPrivate Declare Function GetClientRect Lib "user32" _ (ByVal hWnd As Long, lpRect As RECT) As LongPrivate Type RECT Left As Long Top As Long Right As Long Bottom As LongEnd TypeConst BDR_INNER = &HCConst BDR_OUTER = &H3Const BDR_RAISED = &H5Const BDR_RAISEDINNER = &H4Const BDR_RAISEDOUTER = &H1Const BDR_SUNKEN = &HAConst BDR_SUNKENINNER = &H8Const BDR_SUNKENOUTER = &H2Const BF_RIGHT = &H4Const BF_LEFT = &H1Const BF_TOP = &H2Const BF_BOTTOM = &H8Const EDGE_BUMP = (BDR_RAISEDOUTER Or BDR_SUNKENINNER)Const EDGE_ETCHED = (BDR_SUNKENOUTER Or BDR_RAISEDINNER)Const EDGE_RAISED = (BDR_RAISEDOUTER Or BDR_RAISEDINNER)Const EDGE_SUNKEN = (BDR_SUNKENOUTER Or BDR_SUNKENINNER)Const BF_RECT = (BF_LEFT Or BF_RIGHT Or BF_TOP Or BF_BOTTOM)
In the Form_Paint event, put this code where you wish to draw the rectangle:
Private Sub Form_Paint() Static Tmp As RECT Static TmpL As Long TmpL = GetClientRect(hWnd, Tmp) TmpL = DrawEdge(hDC, Tmp, EDGE_SUNKEN, BF_RECT)End Sub
If the rectangle doesn’t draw, do a Debug.Print on the TmpL variable. It should read a nonzero value upon success.