کلینیک فوق تخصصی اکسس ( کاربرد vba در اکسس )

کلینیک فوق تخصصی اکسس ( کاربرد vba در اکسس )

به اشتراک گذاری اطلاعات کسب شده در اکسس از سایت آفیس و سایت های تخصصی خارجی
کلینیک فوق تخصصی اکسس ( کاربرد vba در اکسس )

کلینیک فوق تخصصی اکسس ( کاربرد vba در اکسس )

به اشتراک گذاری اطلاعات کسب شده در اکسس از سایت آفیس و سایت های تخصصی خارجی

DRAWITEM ... LISTBOX



Type NCCALCSIZEPARAM

rgrc(3) As RECT

lpos As WINDOWPOS

End Type



lParam

If wParam is TRUElParam points to an NCCALCSIZE_PARAMS structure that contains information an application can use to calculate the new size and position of the client rectangle.

If wParam is FALSElParam points to a RECTstructure. On entry, the structure contains the proposed window rectangle for the window. On exit, the structure should contain the screen coordinates of the corresponding window client area


Function fnListSubClass(ByVal hwnd As LongPtr,ByVal msg As Long,ByVal wParam As LongPtr,ByVal lParam As LongPtr)

Select Case msg

case WM_NCCALCSIZE

CallWindowProc listboxProc,hwnd,msg, wParam, lParam
'what is doing???
RECT* pRect = (RECT*)lParam
pRect->left+=4;
pRect->top+=23;
pRect->bottom+=23;
return 0;

case WM_NCPAINT

hdc=GetDC(hwnd) GetClientRect hwnd,rect
SetRect rect,0,0,4, rect.bottom brush=LoadBitmap(GetModuleHandle(0), MAKEINTRESOURCE(IDB_BORDER))
newBrush=CreatePatternBrush(brush)
oldBrush=SelectObject(hdc, newBrush) FillRect hdc,rect,newBrush SelectObject hdc, oldBrush
DeleteObject newBrush
DeleteObject oldBrush
DeleteObject brush
UpdateWindow hwnd
ReleaseDC hwnd, hdc
Exit Function



fnListSubClass=CallWindowProc(listboxProc, hwnd

(msg, wParam, lParam,


End Function 


Function WinProc(ByVal hwnd As LongPtr,ByVal msg As Long,ByVal wParam As LongPtr,ByVal lParam As 
(LongPtr

CASE WM_SHOWWINDOW,WM_CREATE 

listboxProc=SetWindowLongPtrA(listbox, GWL_WNDPROC,AddressOf fnListSubClass)

SendMessage listbox,WM_SETFONT, CreateFont=tahoma16, true

Case WM_DRAWITEM

Dim pdis AS DRAWITEMSTRUCT
CopyMemory pdis,ByVal lParam,40

if pdis.itemID=-1 Then Exit Function

Dim txt As String*40

SendMessage pdis.hwndItem,LB_GETTEXT,pdis.itemID, text
(itemLength=Len(text



if(pdis.itemAction=ODA_FOCUS Or pdis.itemState And ODS_FOCUS) Then 

(SetTextColor pdis.hDC,RGB(255,255,255

(SetBkColor pdis.hDC,RGB(51,94,168

FillRect pdis.hDC,pdis.rcItem

((CreateSolidBrush(RGB(51,94,168,

  
Else

(SetTextColor pdis.hDC,RGB(0,0,0

(SetBkColor pdis.hDC,RGB(255,255,255

FillRect pdis.hDC,pdis.rcItem

((CreateSolidBrush(RGB(255,255,255,


End if 


DrawTextExW pdis.hDC,text,itemLength, pdis.rcItem,DT_CENTER Or DT_END_ELLIPSIS,0



if(pdis.itemState=ODS_FOCUS) Then DrawFocusRect pdis.hDC,pdis.rcItem
End if 

CopyMemory ByVal lParam,pdis,40

Case WM_DESTROY
SetWindowLongPtrA hwnd,GWL_WNDPROC,listboxProc





WM_NCCREATE

We handle WM_NCCREATE because we want to associate so data with the LISTBOX and make a minor modification to the LISTBOX style. Creating our data is a simple and store in the window properties.

We modify the style by adding the WS_HSCROLL if the LISTBOX doesn't already have it. Without this style the horizontal scrollbar won't show no matter what we do.

WM_NCDESTROY

Here we simply destroy our data structure and remove it from the window properties. Nothing exciting.



مثالی دیگر از مطالب به اشتراک گذاشته در سایت خارجی 



Code:
Private Sub Form_Load()
 Dim I As Integer
    
 For I = 15 To 0 Step -1
   'Load a List of 0 to 15 with the Item Data
   'Set to the QBColors 0 - 15
   List1.AddItem "Color " & I
   List1.itemData(List1.NewIndex) = QBColor(I)
 Next
    
 For I = 0 To 15
   'Load a List of 0 to 15 with the Item Data
   'Set to the QBColors 0 - 15
   List2.AddItem "Color " & I
   List2.itemData(List2.NewIndex) = QBColor(I)
 Next
    
 'Subclass the "Form", to Capture the Listbox Notification Messages
 lPrevWndProc = SetWindowLong(hwnd, GWL_WNDPROC, AddressOf SubClassedList)
End Sub

Private Sub Form_Unload(Cancel As Integer)
 'Release the SubClassing, Very Import to Prevent Crashing!
 Call SetWindowLong(hwnd, GWL_WNDPROC, lPrevWndProc)
End Sub
.BAS Code

Code:
Option Explicit

Public Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
End Type

Public Type DRAWITEMSTRUCT
        CtlType As Long
        CtlID As Long
        itemID As Long
        itemAction As Long
        itemState As Long
        hwndItem As Long
        hdc As Long
        rcItem As RECT
        itemData As Long
End Type

Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Public Declare Function CreateSolidBrush Lib "gdi32" (ByVal crColor As Long) As Long
Public Declare Function FillRect Lib "user32" (ByVal hdc As Long, lpRect As RECT, ByVal hBrush As Long) As Long
Public Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Public Declare Function SetBkColor Lib "gdi32" (ByVal hdc As Long, ByVal crColor As Long) As Long
Public Declare Function SetTextColor Lib "gdi32" (ByVal hdc As Long, ByVal crColor As Long) As Long
Public Declare Function TextOut Lib "gdi32" Alias "TextOutA" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal lpString As String, ByVal nCount As Long) As Long
Public Declare Function DrawFocusRect Lib "user32" (ByVal hdc As Long, lpRect As RECT) As Long
Public Declare Function GetSysColor Lib "user32" (ByVal nIndex As Long) As Long

Public Const COLOR_HIGHLIGHT = 13
Public Const COLOR_HIGHLIGHTTEXT = 14
Public Const COLOR_WINDOW = 5
Public Const COLOR_WINDOWTEXT = 8
Public Const LB_GETTEXT = &H189
Public Const WM_DRAWITEM = &H2B
Public Const GWL_WNDPROC = (-4)
Public Const ODS_FOCUS = &H10
Public Const ODT_LISTBOX = 2

Public lPrevWndProc As Long

Public Function SubClassedList(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
 Dim tItem As DRAWITEMSTRUCT
 Dim sBuff As String * 255
 Dim sItem As String
 Dim lBack As Long
    
 If Msg = WM_DRAWITEM Then
   'Redraw the listbox
   'This function only passes the Address of the DrawItem Structure, so we need to
   'use the CopyMemory API to Get a Copy into the Variable we setup:
   Call CopyMemory(tItem, ByVal lParam, Len(tItem))
        
   'Make sure we're dealing with a Listbox
   If tItem.CtlType = ODT_LISTBOX Then
     'Get the Item Text
     Call SendMessage(tItem.hwndItem, LB_GETTEXT, tItem.itemID, ByVal sBuff)
            
     sItem = Left(sBuff, InStr(sBuff, Chr(0)) - 1)
            
     If (tItem.itemState And ODS_FOCUS) Then
       'Item has Focus, Highlight it, I'm using the Default Focus
       'Colors for this example.
       lBack = CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT))
                
       Call FillRect(tItem.hdc, tItem.rcItem, lBack)
       Call SetBkColor(tItem.hdc, GetSysColor(COLOR_HIGHLIGHT))
       Call SetTextColor(tItem.hdc, GetSysColor(COLOR_HIGHLIGHTTEXT))
       TextOut tItem.hdc, tItem.rcItem.Left, tItem.rcItem.Top, ByVal sItem, Len(sItem)
       DrawFocusRect tItem.hdc, tItem.rcItem
     Else
       'Item Doesn't Have Focus, Draw it's Colored Background
       'Create a Brush using the Color we stored in ItemData
       lBack = CreateSolidBrush(tItem.itemData)
       'Paint the Item Area
       Call FillRect(tItem.hdc, tItem.rcItem, lBack)
                
       'Set the Text Colors
       Call SetBkColor(tItem.hdc, tItem.itemData)
       Call SetTextColor(tItem.hdc, IIf(tItem.itemData = vbBlack, vbWhite, vbBlack))
       
       'Display the Item Text
       TextOut tItem.hdc, tItem.rcItem.Left, tItem.rcItem.Top, ByVal sItem, Len(sItem)
     End If
            
     Call DeleteObject(lBack)
     
     'Don't Need to Pass a Value on as we've just handled the Message ourselves
     SubClassedList = 0
     Exit Function
   End If
 End If
    
 SubClassedList = CallWindowProc(lPrevWndProc, hwnd, Msg, wParam, lParam)
End Function


فقط در CopyMemory سایز ۴۰ را به آرگومان سومش تخصیص دهید و از ByVal lParam استفاده کنید.


در مورد LB_GETTEXT  : 


Return value

The return value is the length of the string, in TCHARs, excluding the terminating null character. If wParam does not specify a valid index, the return value is LB_ERR.

     Remarks

If the list box has an owner-drawn style but not the LBS_HASSTRINGS style, the buffer pointed to by the lParam parameter receives the value associated with the item (the item 

(data


ListBox در InputBox




Vb Uses Unicode For Text String hence delcare SendMessageW instead Of SendMessageA****



: Important Notes

Use -----> LBS_OWNERDRAWFIXED Or LBS_HASSTRINGS 

use -----> SendMessageW,   /   TextoutW

 To Add Item it is important to Use SendMessageA And Byval  "Item" you want to add like 

"SendMessageA hlist, &H180, 0, ByVal "FFF




case WM_DRAWITEM

Dim Buff As String * 255 ' important

GetClientRect pdis.hwndItem, pdis.rcItem

    r = pdis.rcItem

    l = SendMessageW(pdis.hwndItem, LB_GETTEXT, pdis.itemID, ByVal Buff

    SendMessageA pdis.hwndItem, LB_GETITEMRECT, pdis.itemID, r

    TextOutW pdis.hdc, r.Left, r.Top, ByVal Buff, l



"SendMessageA hlist, &H180, 0, ByVal "FFF

       "SendMessageA hlist, &H180, 0, ByVal "HHT

       "SendMessageA hlist, &H180, 0, ByVal "123E

       "سلام" SendMessageA hlist, &H180, 0, ByVal 

        "حاجی"SendMessageA hlist, &H180, 0, ByVal









if pdis.itemid mod 2=. then SetTextColor Else SetTextColor


If pdis.itemAction = ODA_SELECT Then

    ( l = SendMessageW(pdis.hwndItem, LB_GETTEXT, pdis.itemID, ByVal Buff

     SetWindowTextW hwnd, ByVal Buff

     End If










Static OldRect

If pdis.itemAction = ODA_SELECT Then

         ( l = SendMessageW(pdis.hwndItem, LB_GETTEXT, pdis.itemID, ByVal Buff

          SetWindowTextW hwnd, ByVal Buff

          r.Left = r.Left + 15

          (FillRect pdis.hdc, r, GetSysColorBrush(0

          InvalidateRect pdis.hwndItem, OldRect, 1

          OldRect = r

    End If







%WS_CHILD Or %LBS_OWNERDRAWFIXED Or %LBS_MULTICOLUMN Or %LBS_NOTIFY Or %WS_TABSTOP Or %WS_HSCROLL, %WS_EX_CLIENTEDGE
    


پیام WM_PAINT جهت رنگ Client و WM_DRAWITEM برای باتن ساخته شده بجای باتن CANCEL


تست شده 


The WM_PAINT message is sent when the system or another application makes a request to paint a portion 

  of an application's window


The PAINTSTRUCT structure contains information that can be used to paint the.client area of a window

حاوی اطلاعاتی برای استفاده در نقاشی ناحیه ی Client پنجره.



Case WM_PAINT

Dim ps As PAINTSTRUCT

    ( hdc = BeginPaint(lhwnd, ps

     Dim rrc As RECT

     GetClientRect lhwnd, rrc 

  (( FillRect hdc, rrc, CreateSolidBrush(RGB(100, 0, 100

     SetTextColor hdc, vbRed

     TextOutA hdc, 10, 10, "sa", 2

     EndPaint lhwnd, ps

     ReleaseDC lhwnd, hdc


البته غیر از پیام زیر میشود با پیام WM_CTLCOLORBTN  هم  رنگ باتن  را تغییر داد که lParam میشود هندل باتن و wParam هم هندل DC میشود


Case WM_DRAWITEM

   Dim pDIS As DRAWITEMSTRUCT

   Dim state

   (CopyMemory pDIS, ByVal lParam, Len(pDIS

  ( hdc = GetDC(pDIS.hdc

   Dim p As RECT

   p = pDIS.rcItem

   state = pDIS.itemState

  GetClientRect can, p

   If pDIS.CtlID = 2 Then

   If state = 272 Then       

  RoundRect hdc, p.Left, p.Top, p.Right, p.Bottom, 16, 16  

ReleaseDC can, hdc  

  Else         

  RoundRect hdc, p.Left, p.Top, p.Right, p.Bottom, 4, 4       

  ReleaseDC can, hdc      

 End If     

   End If

   (CopyMemory ByVal lParam, pDIS,Len(pDIS



زمان کلیک روی باتن کنسل  مکث عمل RounRect را نمایش داده و پنجره بسته میشود.


If state = 785 Then  '272
  RoundRect hdc, p.Left, p.Top, p.Right, p.Bottom, 16, 16
  Sleep 400
  ReleaseDC can, hdc

If (pDIS.itemState And???
ODS_SELECTED)=ODS_SELECTED Then




طبق داکیومنت آفیس  (WM_CTLCOLORBTN) :

در موارد بالا حتما باید BS_OWNERDRAW تنظیم شود برای کل باتن ها که هندل میشود هندل Dlg و برای باتن خاص هندل همان باتن فقط ،   setwindowlongptra را در WIN64 ببینید.
See For Button Control button-styles
See For Static Control static-control-styles
wParam
An HDC that specifies the handle to the display context for the button
lParam
)An HWND that specifies the handle to the button
getdlgitem : Retrieves a handle to a control in the 
(specified dialog box

hdc=wParam '
Case WM_CTLCOLORBTN
if lparam=GetDlgItem(hwnd,IDCANCEL) then
.
End if
Exit Function



The idea is to add your own Windows message handler, you can do this using 
.SetWindowsHookEx function
Don't forget : Before terminating, an application must call the UnhookWindowsHookEx function to free 
system resources associated with the hook