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

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

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

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

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

ساخت باتن کشویی


بسیار ساده ولی پر دردسر 


      Btn0        Bt t1

Btn1        Btnt2

Btn2       Btnt3

Btnt4                   



طبق نام های بالا  کنترل هایی از نوع باتن  در فرم ساخته شده در کنار هم و زیر هم دقیقا مثل موارد فوق الذکر، تابعی نوشته شد که در زمان اتفاق افتادن رویدادکلیک باتنی از باتن های سمت چپ   کل باتن های سمت راست به زیر آن انتقال یابد .


 Function Btn(Bt As Control3) As Doble

For i=1 to 4

Controls("Btnt" & i).Left=Bt.Left+300

 موقعیت پراپرتی TOP هر یک از کنترل های سمت راست میشود ( فرضا Btnt1 میشود Btn0.Top به اضافه ی عرضش و Btnt2 میشود Btn0.Top + Btn.Height +Btnt2.Height

Controls("Btnt" & i).Top=Bt.Top+Bt.Height+(i-1)*Controls("Btnt" & i).Height

(Btn=Controls("Btnt4".Top

Next


یا بصورت زیر 


Function Btn(Bt As Control) As Double

b = Bt.Top

For i = 1 To 4

Controls("Btnt" & i).Left = Btn0.Left+300

Controls("Btnt" & i).Top = b + Controls("Btnt" & i).Height * i

Btn = Controls("Btnt" & i).Top

Next

End Function


چنانچه هر یک Toppadding خودش را داشته باشه فرضا بین باتن های سمت راست هر کدام فواصل متغیری باشد باید آنها را هم در نظر بگیرید ولی معمولا باتن ها را بهم بچسبانید تا نیاز به کد نویسی اضافه تری نباشد.


در رویداد کلیک Btn0 میتوان نوشت که اولا Btnt ها زیر آن بیاید و Btn1 و Btn2 در زیر Btnt ها قرار گیرد 


()Private Sub Btn0_Click

Btn1.Top = Btn(Btn0) + Btnt4.Height

Btn2.Top = Btn1.Top + Btn1.Height

End Sub


()Private Sub Btn1_Click

Btn1.Top=Btn0.Top+Btn0.Height

(Btn2.Top=Btn(Btn1

End Sub 


()Private Sub Btn2_Click

Btn1.Top = Btn0.Top + Btn0.Height

Btn2.Top=Btn1.Top+Btn0.Height

(Call Btn(Btn2

End Sub



تست شده طبق فایل GIF زیر ، نام ها در کپشن باتن ها نوشته شد تا گیج کننده نباشد.  

















SETMARGINS IN EDIT CONTROL




EC_LEFTMARGIN =&H1
            EC_RIGHTMARGIN =&H2

EM_SETMARGINS=&HD3


  :  lParam


The HIWORD specifies the new width of the right margin, in pixels. This value is ignoredif wParam does 

.notinclude EC_RIGHTMARGIN






EM-SETMARGINS







CreatePen ساخت قلم برای ترسیم



HPEN CreatePen( int iStyle, int cWidth, COLORREF color );


()Edit::OnNcPaint

pDC=GetDC( ) ? GetWindowDC
GetWindowRect Edithwnd,Crect 
OffsetRect Crect,-rect.left,-rect.top
'Draw a single line around the outside
(brush=RGB( 255, 0, 0
FrameRect pDC,Crect,brush ReleaseDC hwnd,pDC


Const PS_SOLID = 0
Const PS_DASH = 1
Const PS_DOT = 2
Const PS_DASHDOT = 3
Const PS_DASHDOTDOT = 4
Const PS_NULL = 5
Const PS_INSIDEFRAME = 6



((hPen=CreatePen(PS_DASH,0,RGB(0,255, 0
(hOldPen=SelectObject(hDC,hPen
Ellipse hDC, 100, 150, 350, 300
SelectObject hDC, hOldPen
DeleteObject hPen




مورد زیر طبق شکل تست شده 


حتما در WndProc در پیام SHOWWINDOW تابع زیر اعمال گردد
SetWindowPos hwnd,0,0,0,0,0,SWP_FRAMECHANGED 

ساب کلاس کردن  کنترل  Edit 

Public Function SubClassEdit(ByVal hwnd As LongPtr, ByVal Msg As Long, ByVal wParam As LongPtr, _
                            ByVal lParam As LongPtr, ByVal uId As LongPtr, ByVal dwData As LongPtr) As Long
Dim nccsp As NCCALCSIZE_PARAMS
Select Case Msg

Case WM_NCPAINT
     (hdc = GetDC(hwnd
     Dim rClient As RECT
     GetClientRect hwnd, rClient
    ( hpen = CreatePen(ps_solid, 2, vbRed
    ( holdpen = SelectObject(hdc, hpen
     RoundRect hdc, rClient.Left - 2, rClient.Top - 2, rClient.right + 2, rClient.bottom + 2, 6, 6
     ReleaseDC hwnd, hdc
     DeleteObject holdpen
Case WM_DESTROY
      RemoveWindowSubclass hwnd, SubClassEdit, 0
      End Select
      
(SubClassEdit = DefSubclassProc(hwnd, Msg, wParam, ByVal lParam
                            
End Function


SWP_FRAMECHANGED 0x0020

Applies new frame styles set using the SetWindowLongfunction. Sends a WM_NCCALCSIZE message to the window, even if the window's size is not being changed. If this flag is not specified, WM_NCCALCSIZEis sent only when the window's size 
.is being changed







BUTTON_CLICK ( ترسیم لبه در پنجره کلاس 32770# )



در BS_OWNERDRAW یا خود Button  کار نمی کند نتیجتا ترسیم شد ( منظور ناحیه ای که در تصویر پایین داخلش  تکست Inside ترسیم شده) .   DrawEdge و DrawTextA


dim rr as RECT

If wMsg = WM_PAINT Then


        z1.Left = 285 + GetSystemMetrics(SM_CYFRAME) * 3 ' 296

        z1.right = 348 + GetSystemMetrics(SM_CYFRAME) * 2 ' 355

        z1.Top = 63 + GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME) * 2 ' 95

        z1.bottom = 86 + GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME) + 2 ' 115

     

    (WindProc = DrawEdge(GetWindowDC(hwnd), z1, EDGE_RAISED, BF_RECT + BF_ADJUST

End If


If wMsg = WM_LBUTTONDOWN Then 'WM_MOUSEMOVE

       

       Dim cp As POINTAPI

SetRect rr, 285, 63, 348, 86

      

      GetCursorPos cp

      ScreenToClient hwnd, cp


rr.Left = rr.Left + 2

       rr.right = rr.right - 2

       rr.Top = rr.Top - cp.y + 2

       rr.bottom = rr.bottom - cp.y - 2



If PtInRect(rr, cp.x, cp.y) Then


End If 



اگر شکل را مشاهده کنید زمان فشردن باتن سمت چپ ماوس در مستطیل موردنظر با مختصات صفحه در قسمت کپشن ویندو هم IN ارسال میشود 

















CustomButton_MouseMove



WM_MOUSEMOVE
Dim pt As POINTAPI
Dim cursorPoint As Longptr 
Dim rc As RECT
(pt.x=loword(lparam
(pt.y=hiword(lparam
(cursorPoint=ScreenToClient (hwnd,pt???
rc.left=0
rc.right=0
rc.right=rc.left+5
rc.bottom=rc.top+5
(If PtInRect(rc, cursorPoint
"SetWindowTextA hwnd,"in
End if 


wParam  : virtual keys like MK_LBUTTON(Mouse Key 
(Left 

lParam
loword از lparam یا (Clng(lparam And 65535 نشاندهنده ی مختصات x کرسر 
The low-order word specifies the x-coordinate of the cursor. The coordinate is relative to the upper-left 
.corner of the client area
Hiword از lparam یا (Clng(lparam \ 65535 نشاندهنده ی مختصات y کرسر 
The high-order word specifies the y-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.


Return value

If an application processes this message, it should 
.return zero




Private oldUserData As LongPtr
Private oldWinProc As LongPtr


=oldUserData 
(GetWindowLongPtr(hwnd,GWLP_USERDATA
oldWinProc=SetWindowLongPtr(hwnd,GWL_WNDPROC,Addressof 
(WinProc


WinProc
Select Case uMsge


Case WM_MOUSMOVE
.
End Select

=userDataToRestore
(SetWindowLongPtr(GWL_USERDATA,oldUserData
)WinProc=CallWindowProc
(oldWinProc,hWnd,uMsg,wParam,lParam
SetWindowLongPtr(GWL_USERDATA,userDataToRestore
End Function



()OnNcPaint

static BOOL before=FALSE
 
if  not before Then 'If first time, the OnNcCalcSize function will be called

SetWindowPos 0(hwnd),0,0,0,0, SWP_FRAMECHANGED Or SWP_NOMOVE Or SWP_NOSIZE before=TRUE
DrawBorders

End if



prect
oldrect

NCCALCSIZE
Static p As RECT


Dim nccsp As NCCALCSIZE_PARAMS
(CopyMemory nccsp,ByVal lParam,Len(lParam
(prect=nccsp.rgrc(0
oldrect=prect

CallWindowProc hWnd, wMsg, wParam, lParam


p.left=prect.left - oldrect.left
p.right=oldrect.right - prect.right
p.Top=prect.top-oldrect.top
p.Bottom=oldrect.bottom-prect.bottom

(p.right=p.right-GetSystemMetrics(SM_CXVSCROLL

ret 
WinProc=WVR_VALIDRECTS


WMNCPAINT : GetButtonRect
Static btnrect

CallWindowProc hWnd, wMsg, wParam, lParam

GetWindowRect hwnd,Winrect
OffsetRect Winrect, -Winrect.left, -Winrect.top

btnrect.right=btnrect.right-p.Right
btnrect.top=btnrect.top+p.Top
btnrect.bottom=btnrect.bottom-p.Bottom
btnrect.left=btnrect.right 
(GetSystemMetrics(SM_CXVSCROLL-


(hdc=GetWindowDC(hwnd

FillRect hdc,btnrect
(GetSysColorBrush(COLOR_BTNFACE,
 

WM_NCPAINT=&H85
WM_NCCALCSIZE=&H83

 * WM_NCCALCSIZE  flags

WVR_ALIGNTOP=&H10
WVR_ALIGNLEFT=&H20
WVR_ALIGNBOTTOM=&H40
WVR_ALIGNRIGHT=&H80
WVR_HREDRAW=&H100
WVR_VREDRAW=&H200
(WVR_REDRAW=(WVR_HREDRAW+ WVR_VREDRAW
WVR_VALIDRECTS=&H400 

Button Menu




docs.appendmenua


(SubclassWindow(hWnd

Somewhere in WM_INITDIALOG handler 

(btnMenu =GetDlgItem(IDC_BTN_ABOUT

("btnMenu.AddMenuItem(IDC_MNU_ONE,"Windows
("btnMenu.AddMenuItem(IDC_MNU_TWO,"Template
(btnMenu.AddMenuItem(IDC_MNU_THREE,"",MF_SEPARATOR
("btnMenu.AddMenuItem(IDC_MNU_FOUR,"Library

MOUSEMOVE / XPOS

WParwm : LBUTTON Or RBUTTON

lParam

Lo مختصات x کرسر را مشخص میکند . مختصات مرتبط با گوشه چپ بالایی از منطقه Client

The low-order word specifies the x-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area

ho مختصات y کرسر را مشخص میکند . مختصات  مرتبط با گوشه چپ بالایی منطقه Client

The high-order word specifies the y-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area


در کل مختصات x و y  گوشه چپ بالایی منطقه Client را مشخص می نماید. 




Case WM_MOUSEMOVE

       

         Dim rw As RECT

         Dim rc As RECT

         Dim pp As POINTAPI

         

         GetWindowRect BtnOk, rw

         pp.x = rw.left

         pp.y = rw.top

         ClientToScreen BtnOk, pp

         GetCursorPos pp

         If Not PtInRect(rw, pp) Then'

         ' MsgBox "rt'

         'End If'

         SetWindowTextA hwnd, pp.x & "," & pp.y & "...." & rw.left & "," & rw.top







اگر ازGetClientRect استفاده کنید مختصات left و Topرا صفر میدهد.


dim rw As RECT

GetWindowRect hwndBtnOk,rw

dim pp as POINTAPI

(pp.x = LoWord(lParam

        ( pp.y = HiWord(lParam

         

          MoveWindow hwndBtnOk, pp.x, pp.y, (rw.right - rw.left), (rw.bottom - rw.top), 1



The &H prefix denotes a number represented in hexadecimal (base 16) notation.

Hexadecimal digits, like decimal, start at 0, but go up to 
.(F (16

e.g. 0 1 2 3 4 5 6 7 8 9 A B C D E F, 10 11 12 13 14 15 16 17 18 19 1A 1B etc.

In C-based languages hexadecimal numbers are prefixed with 0x, eg. 0x10000. This is directly equal to 
H10000 in VB&

Hex To Decimal

WM_NCLBUTTONDOWN



 allow to drag & move userform via control  Label1)
      


Private Declare Function ReleaseCapture Lib "user32" () As Long
 
Private Const WM_NCLBUTTONDOWN = &HA1
Private Const HTCAPTION = 2

Dim hWndForm As Long

Private Sub UserForm_Initialize()
  hWndForm = FindWindow("ThunderDFrame", Me.Caption)
End Sub

Private Sub lb1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
  If Button = xlPrimaryButton Then
    Call ReleaseCapture
    Call SendMessage(hWndForm, WM_NCLBUTTONDOWN, HTCAPTION, ByVal 0&)
  End If
End Sub

GWL_USERDATA



When you send a WM_CLOSE message to a window, it tries to close the window as if the X button were pressed.You cannot know whether the application was closed externally or by clicking the X button

But there is an easy alternative. When you are closing the window externally using WM_CLOSE, you can initialize its 32-bit user data value using the SetWindowLong function before sending the message. In the target application (being closed) you will query this user data using GetWindowLong function and execute your code accordingly.

The user data value is set to 0 by default. You can set it to any non-zero value before sending the WM_CLOSE 
.message


Set the user data value of the target window to -1'
(originally 0)'
WIN32'
SetWindowLong CurrApp,GWL_USERDATA,-1

send closing messgae'
CurrApp is a Handle to the window
&SendMessage CurrApp,WM_CLOSE, 0,ByVal 0

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
    If GetWindowLong(hwnd, GWL_USERDATA) = 0 Then
        MsgBox "Closing from X."
    Else '(if -1)
        MsgBox "Closing externally using WM_CLOSE."
    End If
End Sub

CreateWindowEx


 HWND CreateWindowExA

dwExStyle

lpClassName

lpWindowName

dwStyle

X

Y

nWidth

nHeight

hWndParent

hMenu

hInstance

lpParam 


WS_EX_WINDOWEDGE=&H100
WS_EX_TOOLWINDOW=&H80

 :  Window Styles 

WS_BORDER=&H800000
WS_CHILD=&H40000000

WS_POPUP=&H80000000

 : Note 

The windows is a pop-up window. This style cannot' 

be used with the WS_CHILDstyle


Case WM_CREATE/SHOWWINDOW


create window
int style=WS_POPUP And WS_BORDER
int exstyle=WS_EX_TOOLWINDOW
int hwnd=CreateWindowEx(exstyle "xclass"0 style 10 
(10 50 50 0 0 _hinst 0


BS_OWNERDRAW

case WM_CREATE
hWndButton=CreateWindowEx(0, "BUTTON", NULL, 
WS_CHILD Or 
(BS_OWNERDRAW,10,10,80,20,hWnd,IDC_OWNERDRAW,0,0


Type SIZE
x As Long
y As Long
End Type

LPDRAWITEMSTRUCT lpdis =(DRAWITEMSTRUCT*)lParam
SIZE size
[char text[256
("sprintf(text, "%s", "Test

The GetTextExtentPoint32 function computes the'
. width and height of the specified string of text
(GetTextExtentPoint32 lpdis.hDC,text, Len(text),size
(SetTextColor lpdis.hDC,RGB(0, 0, 0
(SetBkColor lpdis.hDC,RGB(255, 255, 0


ExtTextOut lpdis.hDC, ((lpdis.rcItem.right -lpdis.rcItem.left)-size.cx)/2,((lpdis.rcItem.bottom-lpdis.rcItem.top)- size.cy)/2,ETO_OPAQUE And ETO_CLIPPED,lpdis.rcItem,text,Len(text),0)

DrawEdge lpdis.hDC,lpdis.rcItem,(lpdis.itemState & ODS_SELECTED ? EDGE_SUNKEN : EDGE_RAISED ), BF_RECT


: case WM_CREATE
      
       "hButton = CreateWindow("button","Label,
                WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
                100, 200, 
                50 ,20,
                hWnd,(HMENU) BUTTON_ID,
                0,0,

پیام 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

Gradient Button ( باتن با سطح شیب دار) / DrawCloseButton ( رسم باتن کلوز )



Dim rc As RECT
rc.left = 0
rc.top = 0
rc.right = 260
rc.bottom = 80
Dim hpen
draw gradient button'
Dim i As Integer
i=0
Do
((hpen=CreatePen(PS_SOLID,4,RGB(150-i,0,0
SelectObject hdc, hpen
Rectangle hdc, 0, 0 + i, 262, 1 + i
DeleteObject hpen
(SetBkColor hdc,RGB(130,0,0
(SetTextColor hdc, RGB(255,255,255
TextOut hdc,90,27,"Hello World",11
i=i+1
Loop Until i<80

PS_SOLID=0
PS_DASH=1
PS_DOT=2
PS_DASHDOT=3
PS_DASHDOTDOT=4
PS_INSIDEFRAME=6
PS_GEOMETRIC=65536
PS_ENDCAP_FLAT=512
PS_ENDCAP_MASK=3840
PS_JOIN_BEVEL=4096
PS_JOIN_MITER=8192



(DrawCloseButton(HDC hdc
RECT rc
rc.left=0
rc.top=0
rc.right=30
rc.bottom=30
((br=CreateSolidBrush(RGB(0, 0, 0
FillRect hdc,rc,br
(SetBkColor hdc, RGB(0, 0, 0
(SetTextColor hdc,RGB(255, 255, 255
(TextOut hdc,10,8,"X",1