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

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

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

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

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

WM_NCHITTEST در ساب کلاس EDIT Control



تمام موارد کپی شده از داکیومنتِ موجود است  تست شده همراه با تصویر ، ثابت ها نیز از داکیومنت استخراج و قابل مشاهده برای عموم است. لینک ها شما را به مطلب داکیومنت هدایت خواهند نمود.



if the return value of the message response function of WM_NCHITTEST is HTCLIENT, indicating that the mouse clicked on the client area, Windows will send a WM_LBUTTONDOWN message to the window; if the return value of the message response function of WM_NCHITTEST is not HTCLIENT (may be HTCAPTION, HTCLOSE,

HTMAXBUTTON) Etc.), that is, when the mouse clicks on the non-client area, Windows will send a WM_NCLBUTTONDOWN message to the window.



اگر مقدار برگشتی پاسخ پیام تابع، HTCLIENT باشد، نشان می دهد که ماوس روی ناحیه Client کلیک شده . ویندوز یک پیام WM_NCLBUTTONDOWN به پنجره خواهد فرستاد اگر مقدار جواب پیام برگشتی HTCLIENT نباشد ممکن است HTCAPTION یا HTCLOSE و یا حتی HTMAXBUTTON باشد .یعنی زمان کلیک در منطقه خارج از Client ( هر پنجره ای می تواند خود باتن باشد یا کنترل ویرایش یا  دیالوگ باکس ) ویندوز یک پیام WM_NCLBUTTONDOWN به پنجره ارسال می نماید.





تصویر بالا وقتی ماوس داخل کنترل ویرایش است ( Client ) در Caption یا TitleBar عدد یک و وقتی روی بوردر است عدد 18 را مشاهده می نمائید ثابت ها در پائین ذکر شده .




Case 132 ' WM_NCHITTEST
ff = CallWindowProc(HookInputBoxprev, hWnd, uMsg, wParam, lParam)
SetWindowTextA GetParent(hWnd), ff



HTBORDER=18   '<<<<<<

HTBOTTOM=15

HTBOTTOMLEFT=16

HTBOTTOMRIGHT=17

HTCAPTION=2

HTCLIENT=1  ' <<<<<

HTCLOSE=20

HTERROR=-2

HTGROWBOX=4

HTHELP=21

HTHSCROLL=6

HTLEFT=10

HTMENU=5

HTMAXBUTTON=9

HTMINBUTTON=8

HTNOWHERE=0

HTREDUCE=8

HTRIGHT=11

HTSIZE=4

HTSYSMENU=3

HTTOP=12

HTTOPLEFT=13

HTTOPRIGHT=14

HTTRANSPARENT=-1

HTVSCROLL=7

HTZOOM=9




How to Get Border Of NonClientArea



  1. Call GetClientRect() to get the size of the client area.
  2. Call ClientToScreen() to transform client rect to screen coordinates.
  3. Call GetWindowRect() to get the rectangle of the control including NC area, in screen coordinates.
  4. Calculate difference between client rect and window rect coordinates to get size of border (e. g. leftBorderWidth = clientRect.left - windowRect.left).



how-to-set-the-size-of-the-non-client-area-of-a-win32-window-native


win32/gdi/nonclient-area



CoorDinate     ..... PtInRect





در بالا مختصات x و y با پیام WM_MOUSEMOVE و پارامتر lParam و استفاده از loword و hiword آن در Caption ذکر شده برای گرفتن Right مستطیل کنترل ویرایش از تابع GetClientRect استفاده شده.


Case WM_MOUSEMOVE
         GetClientRect GetDlgItem(hwnd, 1000), r1
         GetCursorPos tt
         ScreenToClient hwnd, tt
         mm.x = CLng(lParam And &HFFFF&)  'LoWord(lParam
         mm.y = CLng(lParam \ &HFFFF&)  'HiWord(lParam
        SetWindowTextA hwnd, "Coordinate :(" & mm.x & "," & mm.y & ")" & " &RectR:" & r1.Right & " &tt_X_Y(" & tt.x & "," & tt.y & ")"
           'r1.Left = 0: r1.Right = 30: r1.Top = 0: r1.Bottom = 50
           If PtInRect(r1, mm.x, mm.y) Then
            'SetWindowTextA GetDlgItem(hwnd, 1), "In"
           ElseIf Not PtInRect(r1, mm.x, mm.y) Then
            'SetWindowTextA GetDlgItem(hwnd, 1), "Out"
           End If


در تصویر پائین Right را 1263 زده چون از تابع GetWindowRect کنترل ویرایش با آیدی 4900 استفاده شده . در ضمن اگر ماوس در مختصات خاصی که که مستطیل را تعریف کردیم ( با left و top و right و bottom ) باشد در باتن Ok با آیدی 1 رشته In و اگر خارج باشد رشته Out جایگزین تکست پنجره باتن میشود.( استفاده از تابع PtInRect )


if Points moved inside the edit 's rectangle we specified  in the above code  , the window text of "Ok" button will  be changed to "In" , Otherwise "Out"



Byval StrPtr

"1604;1591;1601;1575;32;1601;1602;1591;32;1608;1575;1585;1583;32;1705;1606;1740;1583"



The InflateRect function increases or decreases the width and height of the specified rectangle. The InflateRect function adds -dx units to the left end and dx to the right end of the rectangle and -dy units to the top and dy to the bottom. The dx and dy parameters are signed values; positive values increase the width and height, and negative values decrease them.



تابع InflateRect عرض و ارتفاع مستطیل ( Rectangle )  را افزایش یا کاهش می دهد . این تابع dx- واحد به چپ و dx واحد به انتهای راست مستطیل و dy- به بالا و dy به پائین اضافه می نماید.پارامترهای dx و dy مقادیر علامت دار هستند .مقادیر مثبت عرض و ارتقاع را افزایش می دهند و مقادیر منفی آنها را کاهش می دهند.




Dim Mpos As POINTAPI
'Retrieves the position of the mouse cursor, in screen coordinates.
 Retval = GetCursorPos(MPos)
'Retrieves a handle to the window that contains the specified point.
hWnd = WindowFromPoint(MPos.x, MPos.y)
'A handle to the window to be tested.
 If CBool(IsWindow(hWnd)) = False Then
Label1.Caption = ""
Exit Sub
End If
Determines whether a window is maximized
IsMaximized = IsZoomed(hWnd)
'Determines whether the specified window is minimized (iconic).
IsMinimized = IsIconic(hWnd)
'Retrieves a handle to the specified window's parent or owner.
ParentWnd = GetParent(hWnd)

 




29 بهمن 1400 : در پی اهانت یک افسر هندی به سردار سلیمانی و رهبر انقلاب،  مردم منطقه بدگام کشمیر به خیابان‌ها ریختند و در حمایت از سردار سلیمانی شعار سردادند و با ماموران پلیس درگیر شدند و اقدام مامور هتاک را محکوم کردند. یکی از افسران هندی در حین عملیات سرشماری یکی از شهرهای کشمیر با ورود به منزل یکی از شهروندان عکس شهید سلیمانی و رهبرانقلاب را که در خانه او بود به آتش می‌کشد. 








کلاس پنجره ها در باکس ورودی پسورد اکسس ( دیتابیس با پسورد )


کلاس پنجره 32770# است و آیدی های کنترل داخل آن با لوپ زدن و استفاده از تابع GetDlgCtrlID گرفته شده




SendMessageA(GetDlgItem(hhWnd, 2213), WM_GETTEXT, wparam,lparam use strptr


wParam تعداد کاراکتری است که به متغیر بافر تخصیص می دهد ( منظور داخل بافر کپی می کند ) و lParam خود متغیر بافر است مثل $Buff ، برای ارسال نوشته  داخل کنترل RichEdit جایی که پسورد را تایپ کردیم  به Caption پنجره والد از تابع SetWindowTextA بهره بردیم دقیقا مثل تصویر زیر






Function NewWindow1(ByVal hWnd As LongPtr,ByVal uMsg As Long,ByVal wParam As LongPtr,ByVal lParam As LongPtr) As LongPtr
Dim lRes As long
NewWindow1=CallWindowProc(oldWindow, hWnd, uMsg, wParam, lParam)
Select Case uMsg
   Case &H133
   Case &138
   SetBkMode wParam,1
   wParam, RGB(255, 0, 0)
NewWindow1=GetStockObject(8)
   Case WM_NCHITTEST
 lRes=DefWindowProc(hWnd,uMsg,wParam,lParam)
   '   1  : Client
   '   2 :  Caption
   '   wm-nchittest
   Case Else
End Select
End Function


منظور نوشته زیر این است که اگر شما از DefWindowProc استفاده کنید تغییر رنگ ناحیه Static امکانپذیر نیست و این تابع رنگ پیش فرض سیستم را انتخاب می کند پس سعی بیهوده نکنید!!!


By default, the DefWindowProc function selects the default system colors for the static control.


setwindowsubclass



Declare PtrSafe Function SetWindowSubclass Lib "comctl32" (ByVal hWnd As LongPtr, ByVal pfnSubclass As LongPtr, _

  ByVal uIdSubclass As LongPtr, ByVal dwRefData As LongPtr) As LongPtr


Declare PtrSafe Function RemoveWindowSubclass Lib "comctl32" (ByVal hWnd As LongPtr, ByVal pfnSubclass As LongPtr, _

  ByVal uIdSubclass As LongPtr) As LongPtr


Declare PtrSafe Function DefSubclassProc Lib "comctl32" (ByVal hWnd As LongPtr, ByVal uMsg As Long, _

  ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr






Dim hNotePad As Long
Dim hEdit As Long
hNotePad = FindWindow("NotePad", vbNullString)
hEdit = FindWindowEx(hNotePad, 0, "Edit", vbNullString)
Call SendMessage(hEdit, WM_SETTEXT, 0, ByVal "abc")
'StrPtr : Transfer Unicode
'Const WM_SETTEXT = &HC


CopyMemory  nml,ByVal lParam,,LenB(nml)

CopyMemory  lParam,,ByVal nml,LenB(nml)




SubClassing ( Tested Successfully ) 


وقتی SubClass می کنید در واقع پنجره جدیدی ساخته شده و پنجره قدیمی میشود Default.لذا زمان خروج از New به Prev یا Default منتقل میشوید. اگر حذف بدرستی انجام نشود Crash حتمی است  و در نهایت مجبور خواهید شد با Ctrl+Shift+Esc  به Task Manager رفته و اپلیکیشن را End Process  کنید !!! متاسفم چاره ای نیست برای همه پیش می آید حتی باتجربه ها


OnTimer : 

Use FindWindowA  To Get Handle For the Window Class  "#32770"

if HandleWindow<>0  And hHook=0 Then

hHook=SetWindowsHookEx(WH_CBT,AddressOf NewHook,0&,GetCurrentThreadId)

Me.TimerInterval=0


Crash در این قبیل موارد طبیعی است و می بایست قبل از انجام همچین موارد غیر اصولی  که آفیس هم توصیه نمی کند ، حتما یک بک آپ از فایل تهیه شود تا در صورت خرابی فایل فایل جایگزین داشته باشید!!!



Function NewHook(nCode,wParam,lParam)

NewHook=CallNextHookEx(hHook,nCode,wParam,lParam)

If nCode=5 Then 

      If GetClass(wParam)=""32770" Then 

              UnhookWindowsHookEx hHook

              SetWindowSubclass wParam,AddressOf SubClass,1,0

      End If 

End If

End Function


Function SubClass(hWnd,uMsg,wParam,lParam)

Dim hBr As LongPtr

Dim WinR As RECT

Dim WinP1 As POINTAPI,WinP2 As POINTAPI

SubClass=DefSubClassProc(hWnd,uMsg,wParam,lParam)

Select Case uMsg

            Case WM_CREATE

                  hBkColor=RGB(100,100,100)

                  hTxtColor=RGB(200,0,100)

                 hBr=hBkColor 'GetStockObject(8)

           Case WM_ERASEBKGND

'البته مختصات صفحه باید با تابع ScreenToClient به مختصات کلایِنت تبدیل شود اگر این پیام توسط Parent یا والد Recieve شود رنگ بک گراند پنجره عوض خواهد شد. ( به رنگ دلخواه شما از پالت رنگ آمیزی )  RGB

  

          Case  WM_CTLCOLORSTATIC

'در اینجا رنگ داخل ناحیه استاتیک و نوشته هاش  که Prompt است عوض می شود

                SetBackColor wParam,hBkColor

                SetTextColor wParam,hTxtColor

               SubClass=hBr

          Case WM_DESTROY,WM_NCDESTROY

'حذف ساب کلاس و هوک در زمان خروج 

               RemoveWindowSubclass

 hWnd,SubClass,1

              ' DeleteObject (hBrush Or hFont)

              hHook=False

End Select

End Function




sputniknews.


free : subclassing-and-hooking-with-visual-basic


free : subclassing-and-hooking-with-visual basic_78aa.pdf




i can not figure out what to do what not  to  do



21 بهمن 1351؛ دلار سقوط کرد



21 بهمن 1400 : ایرنا نوشت: جواد منصوری گفت: آمریکا ژنرال هایزر را فرستاده بود تا یک میلیون آدم بکشد  تا محمدرضا پهلوی بر اوضاع مسلط شود ولی این اتفاق نیافتاد، خداوند نخواست و امام (ره) انقلاب را رهبری و فرماندهی کرد و نهایتا انقلاب پیروز شد.


21 بهمن 1400 : علیرغم انتقاد رهبر انقلاب از افزایش قیمت‌ لوازم خانگی، متاسفانه هنوز شرکتهای بزرگ این حوزه از جمله اسنوا که سودهای غیرمتعارف بالای هزار میلیارد تومانی دریافت می کردند، اقدام به کاهش قیمت نکرده اند، بلکه برخی هنوز دنبال افزایش مجدد قیمت هستند.



22 بهمن 1400 : مدیر بیوتکنولوژی موسسه رازی با بیان اینکه بر اساس مطالعات انجام شده، اثربخشی واکسن کووپارس ۲.۵ تا سه برابر بیش از سینوفارم بوده است، گفت: تزریق دز استنشاقی واکسن رازی منجر به افزایش مقدار آنتی بادی در قسمت‌های بینی و مخاطی شده و هم ورود ویروس به قسمت فوقانی دستگاه تنفسی کمتر شده و در نتیجه انتقال ویروس کمتر اتفاق می‌افتد.











بررسی قرار گرفتن نشانگر ماوس در ناحیه مورد نظر API



تمام این مطالب گردآوری شده از سایت های مختلف است بعضی امتحان شده و تصویر نیز در مطلب قرار داده شده و در بعضی موارد فقط مطلب Copy Paste شده است به بزرگی خودتان ببخشید دوستان 


این تابع تعیین می کند آیا نقطه داخل ناحیه مشخص شده است یا خیر .فرضا یک ناحیه بیضوی درست کرده اید در WM_PAINT و می خواهید زمانیکه Mouse را داخل آن منطقه بردید کاری را برای شما انجام دهد ، lParam در WM_MOUSEMOVE قسمت loword آن xmouse و قسمت hiword آن ymouse است .


The PtInRegion function determines whether the specified point is inside the specified region.


SetRect R, 0, 0, 50, 50
'Create an elliptical region
mRGN = CreateEllipticRgnIndirect(R)

For x = R.Left To R.Right
For y = R.Top To R.Bottom
'If the point is in the region, draw a green pixel
If PtInRegion(mRGN, x, y) <> 0 Then
'Draw a green pixel

setpixel  ' Lib "gdi32"

SetPixel Me.hdc, x, y, vbGreen
ElseIf PtInRect(R, x, y) <> 0 Then
'Draw a red pixel
SetPixel Me.hdc, x, y, vbRed
End If






SubClassing The Window : win64


Private OldWindowProc As LongPtr

Const WM_CONTEXTMENU=&H7b

List_Of_Windows_Messages


Public Function NewWindowProc(ByVal hwnd As LongPtr, ByVal msg  As Long, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr
Const WM_NCDESTROY = &H82
Debug print Hex$(msg)
If msg = WM_NCDESTROY Then

SetWindowLonPtr hwnd,GWL_WNDPROC,OldWindowProc End If

NewWindowProc=CallWindowProc(OldWindowProc,hwnd,msg,wParam,lParam)

End Function







.









SubClassing The Form


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



برای SubClass کردن پنجره حتما پنجره VBE بسته باشد و در صورت لزوم انجام تغییرات حتما از برنامه خارج شده و دوباره وارد شوید.


WikiBooks : SubClassing



Declare Function SetClipboardViewer Lib "user32" (ByVal hwnd As Long) As Long



Private PrevProc As LongPtr

Private Const WM_SETTEXT=&HC As Long


Function WindowProc(ByVal Hwnd As LongPtr,Byval uMsg As Long,ByVal wParam As LongPtr,ByVal lParam As LongPtr)


Select Case uMsg 

 ' SendMessageList

     Case WM_LBUTTONUP

     Case WM_SETTEXT

در این پیام wparam استفاده نمی شود و lparam هم رشته است .

sTemp=StrConv("SubClassing" & Chr(0),VbFromUnicode)

lParam=lParam & "..." & sTemp


 End Select

WindowProc=CallWindowProc(PrevProc,Hwnd,uMsg,wParam,lParam)

End Function


Function SubClassForm(Frm As Form)

PrevProc=SetWindowLongPtr(Frm.hwnd,(-4),AddressOf WindowProc)

End Function


Function UnSubClassForm(Frm As Form)

SetWindowLongPtr Frm.hwnd,(-4),PrevProc

End Function


Form 1 : 

Event:Load

SubClassForm Me

Event UnLoad

UnSubClassForm Me

CommandButton0

SendMessage Me.hwnd,&HC,0&,Byval "This is a test..."


توجه : اگر توابع درست فراخوانی نشوند یا اینکه دیتا تایپ اشتباه باشد یا در جایی که نیاز است ByVal استفاده نشود ، Crash خواهد داد ( وباید از Task Manager یا زدن  کلید ترکیبی ctrl+shift+esc  اکسس اجرایی را ببندید ) و باعث آسیب به دیتا بیس خواهد شد هر چند اکسس قبلش یک BackUp می سازد.


برای اصلاح در محیط VBE حتما از فایل خارج شوید و دوباره وارد فایل شوید و گرنه کلوز باتن فرم در اجرای مجدد فریز شده و می بایست به اپلیکیشن دیگر فوکس کرده یا به دسکتاپ Move کنید و سپس به اکسس بروید . در این صورت پیام ویندوزی هم دریافت نمی گردد.



Private Type MSG
hwnd As Long
message As Long
wParam As Long
lParam As Long
time As Long
pt As POINTAPI

End Type


Private hXLDesk As LongPtr
Private lPrevWnd As LongPtr
Private bXitLoop As Boolean


Public Sub InstallHook()
If lPrevWnd = 0 Then 
hXLDesk =FindWindowEx(FindWindow("XLMAIN",Application.Caption),0, "XLDESK", vbNullString)
lPrevWnd=SetWindowLongPtr(hXLDesk,(-4), AddressOf TransitionalProc)
' Msg pump for safe subclassing !!!! 
MessageLoop
End If
End Sub

Public Sub ClearHook()
'cleanUp.
bXitLoop = True
SetWindowLongPtr hXLDesk,(-4),lPrevWnd 
lPrevWnd = 0
hXLDesk = 0
End Sub 


Private Sub MessageLoop()
Dim aMsg As MSG
bXitLoop = False
On Error Resume Next
'ensure all Msgs are posted during the subclassing.
Do While GetMessage(aMsg, 0, 0, 0) And bXitLoop = False
DoEvents
PostMessage 0,aMsg.message, aMsg.wParam, aMsg.lParam
Loop
End Sub


Dim loword As Long,hiword As Long

Case WM_SETCURSOR
         GetHiLoword lParam, loword, hiword
If hiword = WM_MOUSEMOVE Then
GetCursorPos tPt
End If

Private Sub GetHiLoword (lParam As Long, ByRef loword As Long, ByRef hiword As Long)
loword = lParam And &HFFFF&
hiword = lParam \ &H10000 And &HFFFF&
End Sub



MINMAXINFO


The minimum tracking width (x member) and the minimum tracking height (y member) of the window. This value can be obtained programmatically from the system metrics SM_CXMINTRACK and SM_CYMINTRACK




Declare Function CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpvDest As Any, lpvSource As Any,ByVal cbCopy As Long)


Type POINTAPI

x As Long : y As Long
End Type



Type MINMAXINFO
ptReserved As POINTAPI :ptMaxSize As POINTAPI
ptMaxPosition As POINTAPI :ptMinTrackSize As POINTAPI
ptMaxTrackSize As POINTAPI
End Type

Private Function ISubclass_WindowProc(ByVal hwnd As Long, ByVal iMsg As Long,ByVal wParam As Long,ByVal lParam As Long) As Long 
Dim mmiT As MINMAXINFO
' Copy parameter to local variable for processing
کپی کردن lparam که منبع است به متغیر mmiT که مقصد است 
CopyMemory mmiT, ByVal lParam, LenB(mmiT)
' Minimium width and height for sizing mmiT.ptMinTrackSize.x = 128
mmiT.ptMinTrackSize.y = 128
' Copy modified results back to parameter
CopyMemory ByVal lParam,mmiT, LenB(mmiT) 
End Function 





Declare PtrSafe Function SetWindowSubclass Lib "comctl32" (ByVal hWnd As LongPtr, ByVal pfnSubclass As LongPtr, ByVal uIdSubclass As LongPtr, Optional ByVal dwRefData As LongPtr) As LongPtr

Declare PtrSafe Function RemoveWindowSubclass Lib "comctl32" (ByVal hWnd As LongPtr, ByVal pfnSubclass As LongPtr, ByVal uIdSubclass As LongPtr) As LongPtr

Declare PtrSafe Function DefSubclassProc Lib "comctl32" (ByVal hWnd As LongPtr, ByVal uMsg As Long, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr


TIMER  : 


A millisecond (from milli- and second; symbol: ms) is a thousandth (0.001 or 103 or 1/1000) of a second.


Private Declare PtrSafe Function SetTimer Lib "user32" (ByVal hwnd As LongPtr,ByVal nIDEvent As Long,ByVal uElapse As Long,ByVal lpTimerFunc As LongPtr) As LongPtr

Private Declare PtrSafe Function KillTimer Lib "user32" (ByVal hwnd As LongPtr,ByVal nIDEvent As Long) As Long

Public TimerID As LongPtr

Dim lCount As Long
Sub SetTheTimer()
  lCount = 0
TimerID = SetTimer(0&, 0&, 500, AddressOf TimerProc)
End Sub

Sub KillTheTimer()
  KillTimer 0, TimerID
End Sub


Function TimerProc(ByVal hwnd As LongPtr,ByVal wMsg As Long,ByVal idEvent As LongPtr,ByVal dwTime As Long)
On Error Resume Next 'necessary

lCount = lCount + 1
    Debug.Print "Timer callback " & lCount
    If lCount = 10 Then KillTimer 0, TimerID

End Function



در یکی از برنامه‌های خبری شبکه بی‌بی‌سی عربی، وقتی از «مهدی عفیفی» به عنوان کارشناس درباره مسائل اوکراین پرسش شد، وی پس از مدت کوتاهی بعد از شروع صحبتش درباره این موضوع، ناگهان گفت: «موضوعی که می‌خواهم به آن اشاره کنم این است که بی‌بی‌سی دو سال است که پول برنامه‌های ما را نداده! مسئولان بی‌بی‌سی کجا هستند؟ چگونه می‌خواهید عدم پرداخت پول ما را توجیه کنید؟»











SubClass A Window



برای  ساب کلاس کردن پنجره در 32 بیت : 


Constants used with Windows APIs
Private Const GWL_WNDPROC = -4

Private mHwnd As LongPtr
Public mOldWndProc As LongPtr

Private Sub Comman4_Click()
mHwnd = FindWindowA(vbNullString, Me.Caption)
SetHook
End Sub

Private Sub Form1_Close()
RemoveHook
End Sub

Private Sub SetHook()
mOldWndProc = SetWindowLongPtrA(mHwnd, GWL_WNDPROC, VBA.CLngPtr(AddressOf NewWndProc))
End Sub

Private Sub RemoveHook()
SetWindowLongPtrA mHwnd, GWL_WNDPROC, mOldWndProc
End Sub

Public Function NewWndProc(ByVal hwnd As LongPtr, _
ByVal uMsg As Long, _
ByVal wParam As LongPtr, _
ByVal lParam As LongPtr) As LongPtr

'On Error Resume Next

NewWndProc = CallWindowProcA(mOldWndProc, hwnd, uMsg, wParam, lParam)
End Function

Unfortunately, you cannot rotate text in a WinForms label. If you really want to do it, you have to handle the Paint event and write code to rotate the text.




برای چرخش متن در گزارش از اکتیوایکس ها استفاده می شود ( و دارای Property ها یا Event هااست البته اگر سازنده تعبیه کرده باشد ) که بصورت کنترل acCustomControl است بنابراین بدون کمک از آنها نمی توان تکست را به درجه ای که می خواهید بچرخانید اکسس فقط چرخش در حالت ۹۰ درجه  Vertical دارد..... پس کنترل اکتیو ایکس رو در گزارشات می بایست اضافه کنید بجای لیبل و از پراپرتی های آن استفاده نمائید 

WM_PAINT : 

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


Public Type PAINTSTRUCT
hDc As Long
fErase As Boolean
rcPaint As RECT
End Type

WindowProc(hwnd,uMsg,wParam,lParam) 

Dim ps As PAINTSTRUCT
Dim hDC,hBrushAs LongPtr

Select Case uMsg
   case WM_DESTROY
          PostQuitMessage(0)
         SelectObject hDC,hOldBrush
         DeleteObject hBrush
         WindowProc=0 ' False
   case WM_PAINT
hdc = BeginPaint(hwnd, &ps)
hBrush=CreateSolidBrush(Rgb)
hOldBrush=SelectObject(hDC,hBrush)
FillRect(hdc, &ps.rcPaint, hBrush)
EndPaint hwnd, &ps
WindowProc=0
End Select
WindowProc=DefWindowProc(hwnd, uMsg, wParam, lParam)






توابع API به حروف بزرگ و کوچک حساسند پس اگر فرضا تابع CreateCompatibleDc ارور Not Find در DLL مربوطه دریافت خواهید کرد چرا ؟ چون DC است نه Dc


















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

رنگ کنترل رسمی ( Custom Control) در SubClaasing



ساب کلاس کردن کنترل ترسیمی  ( تنها یک کنترل ) 

Type  cz As SIZE

cx As Long ' Width

cy As Long  ' Height

End Type 


Type CustCtrl
'Foreground text colour
crForeGnd As Long 
'Background text colour
crBackGnd As Long 
'The font
hFont As Long 
'The control's window handle
hwnd As Long 
End Type 


Painting the control

Whenever windows wants us to update the contents of our window (the client area), a WM_PAINT message will be sent. So, whenever the WM_PAINT message is received, we need to call our control’s painting routine.


case WM_PAINT
 CustCtrl_OnPaint ccp,wParam, lParam

(CustCtrl_OnPaint(ccp As CustCtrl,wParam,lParam

Dim  hdc As Long
Dim ps As PAINTSTRUCTHANDLE
Dim hOldFont As Long
Dim szText As String*200
Dim rc As RECT
Get a device context for this window'
(hdc=BeginPaint(ccp.hwnd,ps
Set the font we are going to use'
(hOldFont=SelectObject(hdc,ccp.hFont
Set the text colours'
SetTextColor hdc,ccp.crForeGnd
SetBkColor  hdc,ccp.crBackGnd
Find the text to draw'
(GetWindowText ccp.hwnd,szText, Len(szText
Work out where to draw'
GetClientRect ccp.hwnd,rc
computes the width and height of the '
.specified string of text'
GetTextExtentPoint32 hdc,szText, len(szText),sz
Center the text'
x=(rc.right-sz.cx)/2
y=(rc.bottom-sz.cy)/2
Draw the text'
ETO_OPAQUE'
The current background color should be used to fill'
the rectangle'
ExtTextOut hdc,x,y,ETO_OPAQUE,rc,szText,len(szText),0
Restore the old font when we have finished'
SelectObject hdc,hOldFont
Release the device context'
EndPaint ccp.hwnd,ps
return 0



The GWL_USERDATA area

Every window in the system has a 32bit integer which can be set to any value. This 4 byte storage area is enough to store a pointer to a structure. We set this integer using SetWindowLong, and retrieve the integer using GetWindowLong. Using this technique, our function will look like this:

(GetCustCtrl(hwnd
return=GetWindowLong(hwnd,GWL_USERDATA



(SetCustCtrl(ByVal hwnd As Long,ByRef ccp As CustCtrl
SetWindowLong hwnd,GWL_USERDATA,ccp

This method is usually used when subclassing a control




Memory allocated by HeapAlloc is not movable. The address returned by HeapAlloc is valid until the memory block is freed or reallocated; the memory 
.block does not need to be locked

To free a block of memory allocated byHeapAlloc, use 
.the HeapFree function


Our custom control will change colour whenever the user clicks the mouse on it. Therefore the next message handler will be for the 
.WM_LBUTTONDOWNmessage

case WM_LBUTTONDOWN
CustCtrl_OnLButtonDown ccp, wParam, lParam


CustCtrl_OnLButtonDown(ByRef ccp As 
(CustCtrl,wParam,lParam
(col=RGB(rnd()*256,rnd()*256,rnd()*256 
Change the foreground colour'
ccp.crForeGnd=col
Use the inverse of the foreground colour'
(ccp.crBackGnd=((col) And &Hffffff
Now redraw the control'
InvalidateRect ccp.hwnd,0,0
UpdateWindow ccp.hwnd
return 0

WM_MOUSEACTIVATE=&H21

'Activates the window, and does not discard the mouse'
.message
MA_ACTIVATE =1

case WM_MOUSEACTIVATE
    SetFocus hwnd
    return MA_ACTIVATE

قلاب کردن پنجره HOOK و دسترسی به کلاس های آن از طریق Subclass کردن


در WIN32 : 

Private Type CWPSTRUCT
lParam As Long
wParam As Long
message As Long
hwnd As Long
End Type
End Type 

Private Const SWP_FRAMECHANGED=&H20
Private Const SWP_NOSIZE=&H1
Private Const SWP_NOZORDER=&H4

Private Const WH_CALLWNDPROC=4
(Private Const GWL_WNDPROC=(-4

Private Const WM_GETFONT=&H31
Private Const WM_CREATE=&H1
Private Const WM_CTLCOLORBTN=&H135
Private Const WM_CTLCOLORDLG=&H136
Private Const WM_CTLCOLORSTATIC=&H138
Private Const WM_CTLCOLOREDIT=&H133
Private Const WM_DESTROY=&H2
Private Const WM_SHOWWINDOW=&H18
Private Const WM_COMMAND=&H111

Private Const BN_CLICKED=0
Private Const IDOK=1
 
Private Const EM_SETPASSWORDCHAR =&HCC

Private INPUTBOX_HOOK As Long
Private INPUTBOX_HWND As Long
Private INPUTBOX_PASSCHAR As String
Private INPUTBOX_FONT As String
Private INPUTBOX_SHOWING As Boolean
Private INPUTBOX_OK As Boolean


Public Function InputBoxEx(ByVal Prompt As String,Optional ByVal Title As String,Optional ByVal FontName As String,Optional ByVal FontSize As Long, Optional ByVal PasswordChar As String,Optional ByVal CancelError As Boolean = False) As String

"INPUTBOX_FONT="MS Sans Serif
INPUTBOX_FONTSIZE=8
INPUTBOX_PASSCHAR=PasswordChar

If Len(FontName) Then INPUTBOX_FONT=FontName
If FontSize>0 Then INPUTBOX_FONTSIZE=FontSize

INPUTBOX_SHOWING = True

INPUTBOX_HOOK=SetWindowsHookEx(WH_CALLWNDPROC,AddressOf 
(HookWindow,0,GetCurrentThreadID
(InputBoxEx=InputBox(Prompt,Title,Context

INPUTBOX_SHOWING=False
 Remove The Hook'
(UnhookWindowsHookEx(INPUTBOX_HOOK
If Not INPUTBOX_OK And CancelError Then Err.Raise vbObjectError + 1, , "User Pressed " & Chr(34) & "Cancel" & Chr(34)
End Function

Private Function HookWindow(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Dim tCWP As CWPSTRUCT
This is where you need to Hook the Inputbox'
(CopyMemory tCWP, ByVal lParam, Len(tCWP
If tCWP.message=WM_CREATE Then
     If ClassName ="#32770" Then
         If INPUTBOX_SHOWING Then
INPUTBOX_HWND=SetWindowLong(tCWP.hwnd,GWL_WNDPROC,AddressOf 
(InputBoxProc
          End If
     End If
End If HookWindow=CallNextHookEx(INPUTBOX_HOOK,nCode,wParam,ByVal lParam)
End Function

Private Function InputBoxProc(ByVal hwnd As Long,ByVal Msg As Long, ByVal wParam As Long,ByVal lParam As Long) As Long

Select Case Msg

    Case WM_COMMAND

        '..Check to see if the OK Button was Pressed'
       lNotify=Val("&H" & Left$(Right$("00000000" & Hex$(wParam), 8), 4))
       lID = Val("&H" & Right$(Right$("00000000" & Hex$(wParam), 8), 4))
       If lNotify = BN_CLICKED Then
          (INPUTBOX_OK = (lID = IDOK
       End If

Case WM_SHOWWINDOW
      GetWindowRect(hwnd, tRECT
     SetWindowPos hwnd,0, tRECT.Left,tRECT.Top,0,0, SWP_NOSIZE Or SWP_NOZORDER Or SWP_FRAMECHANGED)
Case WM_CTLCOLORDLG,WM_CTLCOLORSTATIC,WM_CTLCOLORBTN,WM_CTLCOLOREDIT
.
.
.
If Msg=WM_CTLCOLORSTATIC Then
Set the Font'
lFont=CreateFont(((INPUTBOX_FONTSIZE/72)*96),0,0,0,0,0,0,0,0,0,0,0,0, 
(INPUTBOX_FONT
SelectObject wParam,lFont
End If
tLB.lbColor=INPUTBOX_BACKCOLOR
(InputBoxProc = CreateBrushIndirect(tLB

 Case WM_DESTROY
    Remove the Inputbox Subclassing'
Call SetWindowLong(hwnd,GWL_WNDPROC, INPUTBOX_HWND)
End Select
InputBoxProc=CallWindowProc(INPUTBOX_HWND,hwnd,Msg,wParam,ByVal lParam)
End Function


WH_CBT ( قلاب یا گرفتن پنجره : برای ارسال پیام ازطریق پنجره به زیر پنجره ها Child Window:کنترل پیام های پنجره Window Message)


Tested SuccesFully..... 64 BIT


HOOK/SUBCLASS THE WINDOW







CustomMeSsageBox


(Public Const GWL_WNDPROC = (-4

Public Const HCBT_CREATEWND = 3

Public Const HCBT_DESTROYWND = 4

Public Const HCBT_ACTIVATE = 5


Public Const WM_INITDIALOG = &H110

Public Const WM_COMMAND = &H111

Public Const WM_SYSCOMMAND = &H112






case WM_PAINT
(hdc=BeginPaint(hWnd,ps
((whitebrush=CreateSolidBrush(RGB(0, 0, 0
' Erases the background 
SendMessage(hWnd,WM_ERASEBKGND,
(GetDC(hWnd),0,
(GetClientRect(hWnd,rc
(FillRect(GetDC(hWnd),rc,whitebrush
Can Use DrawEdge' 
 Draw the icon in the client area' 
DrawIcon hdc, 10,20,ByVal  hIcon1' 
(EndPaint(hWnd,ps



You need to handle WM_CTLCOLORDLG. You should return a brush handle. For example, to make the background white:

case WM_CTLCOLORDLG:
    return (INT_PTR)GetStockObject(WHITE_BRUSH);






' Not Tested In VBA Just Following
Code Copied Here

HDC hdcMem

LPDRAWITEMSTRUCT lpdis

Select Case message

case WM_INITDIALOG

'hbm1 and hbm2 are defined globally.

hbm1 = LoadBitmap((HANDLE) hinst, "OwnBit1")

hbm2 = LoadBitmap((HANDLE) hinst, "OwnBit2")

return TRUE

case WM_DRAWITEM

lpdis=(LPDRAWITEMSTRUCT) lParam

hdcMem = CreateCompatibleDC(lpdis.hDC)

if (lpdis->itemState & ODS_SELECTED)

'if selected

SelectObject(hdcMem,hbm2)

else

SelectObject(hdcMem,hbm1)

'Destination

StretchBlt lpdis.hDC,lpdis.rcItem.left,lpdis.rcItem.top,lpdis.rcItem.right-lpdis.rcItem.left,lpdis.rcItem.bottom-lpdis.rcItem.top,hdcMem,0,0,32,32,SRCCOPY

DeleteDC hdcMem

return TRUE

End If

case WM_COMMAND

if (wParam= IDOK Or wParam=IDCANCEL) Then

EndDialog hDlg, TRUE

return TRUE

End If

if (HIWORD(wParam)=BN_CLICKED) Then

Select Case  (LOWORD(wParam))

  case IDB_OWNERDRAW

End Select

End If

case WM_DESTROY

DeleteObject hbm1

DeleteObject hbm2

End Select

return FALSE
' Not Tested
case WM_CREATE
hdc = GetDC(hwnd)
'xPixel = GetDeviceCaps(hdc, ASPECTX) 'yPixel = GetDeviceCaps(hdc, ASPECTY) ReleaseDC hwnd, hdc
SetTimer hwnd,ID_TIMER,50,NULL return 0

case WM_SIZE

xCenter=(cxClient=LOWORD(lParam))/2 yCenter=(cyClient=HIWORD(lParam))/2

cxRadius=cyRadius=min(cxClient, cyClient)/16
cxMove=max(1, cxRadius/2)
cyMove = max(1, cyRadius / 2)

cxTotal=2 * (cxRadius + cxMove)
cyTotal=2 * (cyRadius + cyMove)



case WM_TIMER
hdc = GetDC(hwnd)
hdcMem = CreateCompatibleDC(hdc); SelectObject hdcMem, hBitmap)
BitBlt hdc,xCenter-cxTotal/2, yCenter -cyTotal/2,cxTotal,cyTotal,hdcMem,0,0, SRCCOPY)
ReleaseDC hwnd, hdc
DeleteDC hdcMem




Timers and Animation animation



BackGround Color question-146319

فرآیند پیام ارسال شده به پنجره WindowProc

Subclassing Controls



Declare PtrSafe Function CallWindowProcA Lib "user32" (ByVal lpPrevWndFunc As LongPtr, ByVal hwnd As LongPtr, ByVal Msg As Long, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As Long

Declare PtrSafe Function SetWindowLongPtrA Lib "user32" (ByVal hwnd As LongPtr, ByVal nIndex As Long,ByVal dwNewLong As LongPtr) As Long

(Public Const GWL_WNDPROC = (-4

Global oldwndproc As LongPtr
Global wndHW As LongPtr




: Form_Load

wndHw=Me.Hwnd

(oldwndproc = SetWindowLongPtrA(Me.hwnd, GWL_WNDPROC, AddressOf WndProc


Form_Unload

SetWindowLongPtrA wndHw, GWL_WNDPROC, oldwndproc



Public Function WndProc(ByVal lhwnd As LongPtr, ByVal uMsg As Long, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As Long

If uMsg = 516 Then 'WM_RBUTTONDOWNU           

        'Debug.Print "Intercepted WM_CONTEXTMENU at " & Now                        

       " MsgBox "Mouse Right Button Was Clicked                       

          WndProc=-1                      

ElseIf uMsg = WM_KEYDOWN Then        

           MsgBox wParam                    

             WndProc = True                    

     Else ' Send all other messages to the default message handler     

        (WndProc = CallWindowProcA(oldwndproc, lhwnd, uMsg, wParam, lParam

     End If

     

End Function



Public Const WM_KEYDOWN = &H100
Public Const WM_KEYUP = &H101
Public Const WM_CHAR = &H102
Public Const VK_RETURN = &HD
Public Const VK_UP = &H26
Public Const VK_DOWN = &H28
Public Const VK_HOME = &H24
Public Const VK_LEFT = &H25
Public Const VK_PRIOR = &H21
Public Const VK_LBUTTON = &H1  ' Left mouse button
Public Const VK_RBUTTON = &H2  ' Right mouse button
Public Const VK_MBUTTON = &H4  ' Middle mouse button (three-button mouse)

Public Const SC_SIZE = &HF000&
Public Const SC_MOVE = &HF010&
Public Const SC_MINIMIZE = &HF020&
Public Const SC_MAXIMIZE = &HF030&
Public Const SC_NEXTWINDOW = &HF040&
Public Const SC_PREVWINDOW = &HF050&
Public Const SC_CLOSE = &HF060&














Const WM_NCLBUTTONDOWN As Integer = 161
Const WM_SYSCOMMAND As Integer = 274
Const HTCAPTION As Integer = 2
Const SC_MOVE As Integer = 61456

If (Msg = WM_SYSCOMMAND) And (WParam = SC_MOVE) Then
Return
End If

If (Msg = WM_NCLBUTTONDOWN) And (WParam = HTCAPTION) Then
Return
If (Msg = WM_RBUTTONDOWN) And (WParam = WM_RBUTTONDOWN) Then
Return
End If


وقتی دابل کلیک روی قسمت تایتل بار انجام میشود یا بعبارتی  قسمت کپشن پنجره عمل ماکسیمایز پنجره انجام خواهد گرفت

If umsg = WM_NCLBUTTONDBLCLK And wParam = 2 Then Exit Function

SYsMenu عمل نکردن منوهای تایتل بار یا 

If umsg = WM_SYSCOMMAND And ((wParam = SC_CLOSE) Or (wParam = SC_MINIMIZE) Or (wParam = SC_MAXIMIZE)) Then
Exit Function

مثال دیگر :
    wm-ncdestroy   &H82
If Msg = WM_NCDESTROY Then 
SetWindowLong hWnd,GWL_WNDPROC,OldWindowProc
End If 
If Msg <> WM_CONTEXTMENU Then
NoPopupWindowProc = CallWindowProc(OldWindowProc,hWnd
,Msg,wParam,lParam)

----------------------------------------

 اگر از HOOK  استفاده شود و آیدی WH_MOUSE یا WH_MOUSE_LL


If Wparam=WM_NCLBUTTONDBLCLK Then 
     MouseHookProc=NoneZero
End If



WM_RBUTTONDOWN   wm-rbuttondown   &H204

(20×16)×1.6+4=516 ( DECIMAL )


516÷16=32  

516-(32×16)=4

(516÷16)×10=320

320÷16=20



List Of Windows Message  SendMessageList