| 小ブタ大ブタをコールしません |
2011/11/19
2011/11/12
2011/09/14
2011/08/12
access2010 access2007 アプリケーションウィンドウの中央寄せ -1-
うむ。これは使うことあるので加工させてもらった。
元ネタは、Accessウィンドウをディスクトップの中央に表示する(hatena chips)
マルチモニタ環境で使いたかったので。だけどデュアルモニタまでしか確認してない。
2011/02/14
access2010 Kiosk Form
Option Compare Database
Option Explicit
Public Const HWND_TOP = 0
Public Const HWND_BOTTOM = 1
Public Const HWND_TOPMOST = -1
Public Const HWND_NOTOPMOST = -2
Public Const SW_SHOW = 5
Public Const SW_HIDE = 0
Public Const SWP_NOSIZE = &H1
Public Const SWP_NOMOVE = &H2
Public Const SWP_SHOWWINDOW = &H40
Public Const SW_MAXIMIZE = 3
Declare PtrSafe Function SetWindowPos Lib "user32" _
(ByVal Hwnd As LongPtr, _
ByVal hWndInsertAfter As LongPtr, _
ByVal x As Long, _
ByVal y As Long, _
ByVal cx As Long, _
ByVal cy As Long, _
ByVal wFlags As Long _
) As Long
Declare PtrSafe Function ShowWindow Lib "user32" _
(ByVal Hwnd As LongPtr, _
ByVal nCmdShow As Long _
) As Long
Option Compare Database
Option Explicit
'境界線スタイル:なし、スクロールバーとかは非表示にしておく
Private Sub Form_Close()
ShowWindow Application.hWndAccessApp, SW_SHOW
End Sub
Private Sub Form_Load()
If Not Me.PopUp Then Exit Sub
ShowWindow Application.hWndAccessApp, SW_HIDE
ShowWindow Me.Hwnd, SW_MAXIMIZE
End Sub
Private Sub cmdClose_Click()
DoCmd.Close
End Sub
Private Sub コマンド2_Click()
DoCmd.OpenForm "フォーム2"
End Sub
Private Sub Form_Load()
If Not Me.PopUp Then Exit Sub
SetWindowPos Me.Hwnd, HWND_TOPMOST, 0, 0, _
0, 0, SWP_NOSIZE Or SWP_NOMOVE Or SWP_SHOWWINDOW
End Sub
これでいいか?なんの考慮もしてない。Alt+Tabなど抑制はしない。これ以降はお好みでどうぞ。
なんの考えもなくコード書くもんじゃないと悟った夜。
ラベル:
access 2010,
API
access2010 IAccessible.accStateプロパティ(oleacc)
accStateプロパティを参照して、リボンが最小化されているか調べる。
また、リボンの最小化を実行する。
また、リボンの最小化を実行する。
Option Compare Database
Option Explicit
Const CHILDID_SELF = 0&
Const OBJID_CLIENT = &HFFFFFFFC
Const ROLE_SYSTEM_PUSHBUTTON = &H2B
Declare PtrSafe Function AccessibleChildren Lib "oleacc" ( _
ByVal paccContainer As IAccessible, _
ByVal iChildStart As Long, _
ByVal cChildren As Long, _
ByRef rgvarChildren As Any, _
ByRef pcObtained As Long _
) As Long
Declare PtrSafe Function AccessibleObjectFromWindow Lib "oleacc" ( _
ByVal hWnd As LongPtr, _
ByVal dwId As Long, _
riid As Any, _
ByRef ppvObject As IAccessible _
) As Long
Declare PtrSafe Function IIDFromString Lib "ole32" ( _
ByVal lpsz As LongPtr, _
lpiid As Any _
) As Long
Declare PtrSafe Function FindWindowEx Lib "user32" _
Alias "FindWindowExA" ( _
ByVal hWnd1 As LongPtr, _
ByVal hWnd2 As LongPtr, _
ByVal lpsz1 As String, _
ByVal lpsz2 As String _
) As LongPtr
'リボンが最小化されているかどうか
Function IsRibbonMinimize() As Boolean
Dim IID(0 To 3) As Long, acc As IAccessible, targetAcc As IAccessible
IIDFromString StrPtr("{618736E0-3C3D-11CF-810C-00AA00389B71}"), _
IID(0)
AccessibleObjectFromWindow getHwnd, _
OBJID_CLIENT, _
IID(0), _
acc
Set targetAcc = GetAcc(acc, "リボンの最小化", ROLE_SYSTEM_PUSHBUTTON)
Select Case targetAcc.accState(CHILDID_SELF)
Case 1048576
IsRibbonMinimize = False
Case 1048584
IsRibbonMinimize = True
End Select
End Function
'リボンを最小化する
Sub RibbonMinimize()
Dim IID(0 To 3) As Long, acc As IAccessible, targetAcc As IAccessible
IIDFromString StrPtr("{618736E0-3C3D-11CF-810C-00AA00389B71}"), _
IID(0)
AccessibleObjectFromWindow getHwnd, _
OBJID_CLIENT, _
IID(0), _
acc
Set targetAcc = GetAcc(acc, "リボンの最小化", ROLE_SYSTEM_PUSHBUTTON)
If targetAcc.accState(CHILDID_SELF) = 1048576 Then
targetAcc.accDoDefaultAction CHILDID_SELF
End If
End Sub
Function getHwnd() As LongPtr
Dim pHwnd As LongPtr
pHwnd = FindWindowEx(hWndAccessApp, 0, "MsoCommandBarDock", "MsoDockTop")
pHwnd = FindWindowEx(pHwnd, 0, "MsoCommandBar", "Ribbon")
pHwnd = FindWindowEx(pHwnd, 0, "MsoWorkPane", "Ribbon")
pHwnd = FindWindowEx(pHwnd, 0, "NUIPane", "")
pHwnd = FindWindowEx(pHwnd, 0, "NetUIHWND", "")
getHwnd = pHwnd
End Function
'**** 引用 http://www.ka-net.org/ ****
Function GetAcc(myAcc As IAccessible, _
myAccName As String, _
myAccRole As Long _
) As IAccessible
Dim ReturnAcc As IAccessible
Dim ChildAcc As IAccessible
Dim List() As Variant
Dim Count As Long
Dim i As Long
If (myAcc.accState(CHILDID_SELF) <> 32769) And _
(myAcc.accName(CHILDID_SELF) = myAccName) And _
(myAcc.accRole(CHILDID_SELF) = myAccRole) Then
Set ReturnAcc = myAcc
Else
Count = myAcc.accChildCount
If Count > 0& Then
ReDim List(Count - 1&)
If AccessibleChildren(myAcc, 0&, ByVal Count, List(0), Count) = 0& Then
For i = LBound(List) To UBound(List)
If TypeOf List(i) Is IAccessible Then
Set ChildAcc = List(i)
Set ReturnAcc = GetAcc(ChildAcc, myAccName, myAccRole)
If Not ReturnAcc Is Nothing Then Exit For
End If
Next
End If
End If
End If
Set GetAcc = ReturnAcc
End Function
ラベル:
access 2010,
API
access2010 IAccessible.accLocationメソッド(oleacc)
Option Compare Database
Option Explicit
Const CHILDID_SELF = 0&
Declare PtrSafe Function AccessibleObjectFromWindow Lib "oleacc" ( _
ByVal hWnd As LongPtr, _
ByVal dwId As Long, _
riid As Any, _
ByRef ppvObject As IAccessible _
) As Long
Declare PtrSafe Function IIDFromString Lib "ole32" ( _
ByVal lpsz As LongPtr, _
lpiid As Any _
) As Long
Declare PtrSafe Function FindWindowEx Lib "user32" _
Alias "FindWindowExA" ( _
ByVal hWnd1 As LongPtr, _
ByVal hWnd2 As LongPtr, _
ByVal lpsz1 As String, _
ByVal lpsz2 As String _
) As LongPtr
Function ODocTabsHwnd() As LongPtr
Dim pHwnd As LongPtr
pHwnd = FindWindowEx(Application.hWndAccessApp, _
0, _
vbNullString, _
"ODocTabs")
pHwnd = FindWindowEx(pHwnd, _
0, _
"NetUIHWND", _
vbNullString)
ODocTabsHwnd = pHwnd
End Function
Sub DocumentTabsPos()
Dim IID(0 To 3) As Long, acc As IAccessible
Dim xLeft As Long, yTop As Long, _
xWidth As Long, yHeight As Long
IIDFromString StrPtr("{618736E0-3C3D-11CF-810C-00AA00389B71}"), _
IID(0)
AccessibleObjectFromWindow ODocTabsHwnd, _
CHILDID_SELF, _
IID(0), _
acc
acc.accLocation xLeft, yTop, xWidth, yHeight
Debug.Print xLeft, yTop, xWidth, yHeight
End Sub
ラベル:
access 2010,
API
2011/02/11
access2010 “閉じる”をできるだけ検知
閉じるということをできるだけ検知してみようとしている。
基本的にフォームだけなのだけど、PopUpの時もしくはカスケード表示の時のフォーム上のシステムメニュー(っていうでしたっけ、フォームアイコン右クリメニュー)は検知できていない。
以下コードは64bit用。
基本的にフォームだけなのだけど、PopUpの時もしくはカスケード表示の時のフォーム上のシステムメニュー(っていうでしたっけ、フォームアイコン右クリメニュー)は検知できていない。
以下コードは64bit用。
2011/02/10
access2010 access2007 更新前処理イベント内で閉じるボタンのクリックを判定する方法
YU-TANGさんところの
更新前処理イベント内で閉じるボタンのクリックを判定する方法
をaccess2010でやってみた。
タブ付きドキュメントである場合の件。とりあえず動作することは確認できた。
64bitも動作するようになった。座標をLongLongで渡して成功。そして、デレクティブ。
でも、考えないといけないこと、たくさんあるな。どうしようかな。いずれにせよ、とりあえず。
いろいろ継ぎはぎしてみてBackstageとかOfficemenuもRibbonXmlで一応握ってみたと。
んー、やっぱりとりあえずレベル。たまに失敗している気配はしている。検証甘いから、何も考えずに実装するするにはちょっと心もとない。Accessibleを使うっつーところだけがポイントだろうか。
更新前処理イベント内で閉じるボタンのクリックを判定する方法
をaccess2010でやってみた。
タブ付きドキュメントである場合の件。とりあえず動作することは確認できた。
Option Compare Database
Option Explicit
'*************************
'参照設定
'oleacc.dll
'*************************
Const ROLE_SYSTEM_LIST = &H21
Const ROLE_SYSTEM_PUSHBUTTON = &H2B
Const ROLE_SYSTEM_BUTTONMENU = &H39
Const ROLE_SYSTEM_PROPERTYPAGE = &H26
Const ROLE_SYSTEM_MENUITEM = &HC
Const ROLE_SYSTEM_CLIENT = &HA
Private IsRibbonAction As Boolean
Type POINTAPI
X As Long
Y As Long
End Type
#If VBA7 Then
Private Declare PtrSafe Sub CopyMemory Lib "kernel32" _
Alias "RtlMoveMemory" ( _
Destination As Any, _
Source As Any, _
ByVal Length As LongPtr)
Private Declare PtrSafe Function GetCursorPos Lib "user32" ( _
lpPoint As POINTAPI _
) As Long
#If Win64 Then
Private Declare PtrSafe Function AccessibleObjectFromPoint Lib "oleacc" ( _
ByVal llXY As LongLong, _
ByRef ppvObject As Any, _
ByRef pvarChild As Variant _
) As Long
Private Function PointToLongLong(point As POINTAPI) As LongLong
Dim ll As LongLong, cbLongLong As LongPtr
cbLongLong = LenB(ll)
If LenB(point) = cbLongLong Then
CopyMemory ll, point, cbLongLong
End If
PointToLongLong = ll
End Function
#Else
Private Declare PtrSafe Function AccessibleObjectFromPoint Lib "oleacc" ( _
ByVal xScreen As Long, _
ByVal yScreen As Long, _
ByRef ppvObject As Any, _
ByRef pvarChild As Variant _
) As Long
#End If
#Else
Private Declare Function GetCursorPos Lib "user32" ( _
lpPoint As POINTAPI _
) As Long
Private Declare Function AccessibleObjectFromPoint Lib "oleacc" ( _
ByVal xScreen As Long, _
ByVal yScreen As Long, _
ByRef ppvObject As Any, _
ByRef pvarChild As Variant _
) As Long
#End If
Function IsCloseButtonClicked() As Boolean
Dim xy As POINTAPI, acc As IAccessible
Dim Child As Variant, btnName As String, tabCaption As String
If IsRibbonAction Then
IsCloseButtonClicked = True
IsRibbonAction = False
Exit Function
End If
GetCursorPos xy
#If Win64 Then
AccessibleObjectFromPoint PointToLongLong(xy), acc, Child
#Else
AccessibleObjectFromPoint xy.X, xy.Y, acc, Child
#End If
If acc Is Nothing Then
IsCloseButtonClicked = False
Exit Function
End If
btnName = acc.accName(Child)
tabCaption = CodeContextObject.Caption
If tabCaption = "" Then
tabCaption = CodeContextObject.Name
End If
Select Case acc.accRole(Child)
Case ROLE_SYSTEM_LIST
MsgBox "タスクバー:すべてのウィンドウを閉じる" & _
vbCrLf & btnName
Case ROLE_SYSTEM_PUSHBUTTON
If InStr(1, btnName, "を閉じる") > 1 Then
MsgBox "フォーム閉じるボタン" & _
vbCrLf & btnName
Else
MsgBox "Application閉じるボタン" & _
vbCrLf & btnName
End If
Case ROLE_SYSTEM_BUTTONMENU
MsgBox "システムメニュー:閉じる" & _
vbCrLf & btnName
Case ROLE_SYSTEM_MENUITEM
MsgBox "フォームアイコンダブルクリック" & _
vbCrLf & btnName
Case ROLE_SYSTEM_PROPERTYPAGE
'結果的にこうなる
MsgBox "Applicationアイコンダブルクリック" & _
vbCrLf & btnName
Case Else
MsgBox "不明 もしくは、Backstageのコマンド" & _
vbCrLf & btnName
End Select
IsCloseButtonClicked = True
End Function
'RibbonXmlで検知:フォームが開いていること前提
Sub onActionClose(ctr As Object, CancelDefault)
If Screen.ActiveForm.Dirty Then
MsgBox "RibbonXmlで管理できるコマンド:" & ctr.ID
IsRibbonAction = True
End If
CancelDefault = False
End Sub
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui"> <commands> <command idMso="WindowClose" onAction="onActionClose" /> <command idMso="CloseDocument" onAction="onActionClose" /> <command idMso="FileCloseDatabase" onAction="onActionClose" /> <command idMso="FileExit" onAction="onActionClose" /> </commands> </customUI>a2007でも動作するけどOfficeメニューから閉じる動作については対応は今のところ放置。同様に、BackStageから閉じる場合も反応できない。この辺はリボンカスタマイズでなんとかなるかな。タスクバーから閉じる場合もダメなんす。 a2010Runtimeだけシステムメニューから閉じるの場合反応なし。a2010(x64)についてはからっきし動作しない。調査してみるけど、これは俺には無理かも。AccessibleObjectFromPoint にXYをどのように渡すかだろうか。
64bitも動作するようになった。座標をLongLongで渡して成功。そして、デレクティブ。
でも、考えないといけないこと、たくさんあるな。どうしようかな。いずれにせよ、とりあえず。
いろいろ継ぎはぎしてみてBackstageとかOfficemenuもRibbonXmlで一応握ってみたと。
んー、やっぱりとりあえずレベル。たまに失敗している気配はしている。検証甘いから、何も考えずに実装するするにはちょっと心もとない。Accessibleを使うっつーところだけがポイントだろうか。
ラベル:
access 2010,
API,
MS-Access
2011/01/12
access2010 access2007 GUID取得
以前から使ってたのはちょっとなんだから、見直し。
accessに StringFromGUIDってのがあるから使ってみる。
ふむふむ、StringFromGUIDの引数はByte配列だと。でこうなった。
いっそのことCopyMemoryも無くしちゃえばいいんじゃね?
と、なってさらにこうなった。
そして、ふと、思った。
何の気なしに、VarPtrとかStrPtrとかLongPtrとか使ってるけど、これって本当に大丈夫なのだろうかと。32bitOS+32bitOfficeは問題なかろうと思うけど。
あえて際を行くことはやらなければよいのだろうな。きっと。
accessに StringFromGUIDってのがあるから使ってみる。
ふむふむ、StringFromGUIDの引数はByte配列だと。でこうなった。
Option Compare Database
Option Explicit
Private Type GUID
GUIDData(0 To 15) As Byte
End Type
#If VBA7 Then
Private Declare PtrSafe Function CoCreateGuid Lib "ole32" ( _
pGUID As GUID _
) As Long
Private Declare PtrSafe Sub CopyMemory Lib "kernel32" _
Alias "RtlMoveMemory" ( _
Destination As Any, _
Source As Any, _
ByVal Length As LongPtr)
#Else
Private Declare Function CoCreateGuid Lib "ole32" ( _
pGUID As GUID _
) As Long
Private Declare Sub CopyMemory Lib "kernel32.dll" _
Alias "RtlMoveMemory" ( _
Destination As Any, _
Source As Any, _
ByVal Length As Long)
#End If
Function GetNewGUID() As String
Dim tmpGUID As GUID, tmpData(0 To 15) As Byte
If CoCreateGuid(tmpGUID) = 0 Then
CopyMemory tmpData(0), tmpGUID.GUIDData(0), 16
GetNewGUID = Mid(StringFromGUID(tmpData), 7, 38)
End If
End Function
これで速度はおよそ5倍になった。概ね満足。いっそのことCopyMemoryも無くしちゃえばいいんじゃね?
と、なってさらにこうなった。
Option Compare Database
Option Explicit
#If VBA7 Then
Private Declare PtrSafe Function CoCreateGuid Lib "ole32" ( _
ByVal pGUID As LongPtr _
) As Long
#Else
Private Declare Function CoCreateGuid Lib "ole32" ( _
ByVal pGUID As Long _
) As Long
#End If
Function GetNewGUID() As String
Dim aryGUID(0 To 15) As Byte
If CoCreateGuid(VarPtr(aryGUID(0))) = 0 Then
GetNewGUID = Mid(StringFromGUID(aryGUID), 7, 38)
End If
End Function
さらに速くなったということはない。そして、ふと、思った。
何の気なしに、VarPtrとかStrPtrとかLongPtrとか使ってるけど、これって本当に大丈夫なのだろうかと。32bitOS+32bitOfficeは問題なかろうと思うけど。
あえて際を行くことはやらなければよいのだろうな。きっと。
2011/01/06
office2010 Win32API CopyMemory
Option Compare Database
Option Explicit
#If VBA7 Then
Declare PtrSafe Sub CopyMemory Lib "kernel32" _
Alias "RtlMoveMemory" ( _
Destination As Any, _
Source As Any, _
ByVal Length As LongPtr)
#Else
Declare Sub CopyMemory Lib "kernel32.dll" _
Alias "RtlMoveMemory" ( _
Destination As Any, _
Source As Any, _
ByVal Length As Long)
#End If
ラベル:
access 2010,
API,
MS-Access,
Office 2010,
VBA
2011/01/05
office2010 Win32API 条件付きコンパイル WindowFromPoint
#If VBA7 Then
'************** VBA7共通 **************
Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
Declare PtrSafe Sub CopyMemory Lib "kernel32" _
Alias "RtlMoveMemory" ( _
Destination As Any, _
Source As Any, _
ByVal Length As LongPtr)
'**************************************
#If Win64 Then
'************** VBA7x64用 **************
Declare PtrSafe Function GetWindowLong Lib "user32" _
Alias "GetWindowLongPtrA" ( _
ByVal hwnd As LongPtr, _
ByVal nIndex As Long _
) As LongPtr
Declare PtrSafe Function SetWindowLong Lib "user32" _
Alias "SetWindowLongPtrA" ( _
ByVal hwnd As LongPtr, _
ByVal nIndex As Long, _
ByVal dwNewLong As LongPtr _
) As LongPtr
Declare PtrSafe Function GetTickCount64 Lib "kernel32" () As LongLong
Declare PtrSafe Function WindowFromPoint Lib "user32" ( _
ByVal point As LongLong _
) As LongPtr
Type POINTAPI
x As Long
y As Long
End Type
Function PointToLongLong(point As POINTAPI) As LongLong
Dim ll As LongLong
Dim cbLongLong As LongPtr
cbLongLong = LenB(ll)
If LenB(point) = cbLongLong Then
CopyMemory ll, point, cbLongLong
End If
PointToLongLong = ll
End Function
'***************************************
#Else
'************** VBA7x86用 **************
Declare PtrSafe Function GetWindowLong Lib "user32" _
Alias "GetWindowLongA" ( _
ByVal hwnd As LongPtr, _
ByVal nIndex As Long _
) As LongPtr
Declare PtrSafe Function SetWindowLong Lib "user32" _
Alias "SetWindowLongA" ( _
ByVal hwnd As LongPtr, _
ByVal nIndex As Long, _
ByVal dwNewLong As LongPtr _
) As LongPtr
Declare PtrSafe Function WindowFromPoint Lib "user32" ( _
ByVal xPoint As Long, _
ByVal yPoint As Long _
) As LongPtr
'***************************************
#End If
#Else
'************** Office2007以前 **************
Declare Function GetWindowLong Lib "user32" _
Alias "GetWindowLongA" ( _
ByVal hwnd As Long, _
ByVal nIndex As Long _
) As Long
Declare Function SetWindowLong Lib "user32" _
Alias "SetWindowLongA" ( _
ByVal hwnd As Long, _
ByVal nIndex As Long, _
ByVal dwNewLong As Long _
) As Long
Declare Function GetTickCount Lib "kernel32" () As Long
Declare Function WindowFromPoint Lib "user32" ( _
ByVal xPoint As Long, _
ByVal yPoint As Long _
) As Long
#End If
ラベル:
access 2010,
API,
MS-Access,
Office 2010,
VBA
office2010 Win32API GetWindowText/SetWindowText
#If VBA7 Then
Declare PtrSafe Function SetWindowText Lib "user32" _
Alias "SetWindowTextW" ( _
ByVal Hwnd As LongPtr, _
ByVal lpString As LongPtr _
) As Long
Declare PtrSafe Function GetWindowText Lib "user32" _
Alias "GetWindowTextW" ( _
ByVal Hwnd As LongPtr, _
ByVal lpString As LongPtr, _
ByVal cch As Long _
) As Long
#Else
Declare Function SetWindowText Lib "user32" _
Alias "SetWindowTextW" ( _
ByVal hwnd As Long, _
ByVal lpString As Long _
) As Long
Declare Function GetWindowText Lib "user32" _
Alias "GetWindowTextW" ( _
ByVal Hwnd As Long, _
ByVal lpString As Long, _
ByVal cch As Long _
) As Long
#End If
'textLength = GetWindowText(Hwnd, StrPtr(buffer), Len(buffer))
'成功:終端Null除く文字数 / 失敗:0 / cch超える分は切り捨て
'result = SetWindowText(Hwnd, StrPtr(Strings))
'成功:0 / 失敗:0以外
ラベル:
access 2010,
API,
MS-Access,
Office 2010,
VBA
2011/01/03
office2010 Win32API EnumWindows
Option Compare Database
Option Explicit
Private Const WM_SETTEXT = &HC
Private Const BM_CLICK = &HF5
Private Const IDOK = &H1
Private Const IDC_EDIT = &H8A5
Private pHwnd As LongPtr
'Type UserDefined01
' taskID As Long
' Hwnd As LongPtr
'End Type
Private Declare PtrSafe Function GetWindowText Lib "user32" _
Alias "GetWindowTextA" ( _
ByVal hwnd As LongPtr, _
ByVal lpString As String, _
ByVal cch As Long _
) As Long
'http://msdn.microsoft.com/ja-jp/library/cc410851.aspx
Private Declare PtrSafe Function EnumWindows Lib "user32" ( _
ByVal lpEnumFunc As LongPtr, _
ByVal lParam As Any _
) As Long
'Private Declare PtrSafe Function EnumWindows Lib "user32" ( _
' ByVal lpEnumFunc As LongPtr, _
' lParam As Any _
' ) As Long
Private Declare PtrSafe Function GetWindowThreadProcessId Lib "user32" ( _
ByVal hwnd As LongPtr, _
lpdwProcessId As Long _
) As Long
Private Declare PtrSafe Function GetLastActivePopup Lib "user32" ( _
ByVal hwndOwnder As LongPtr _
) As LongPtr
Private Declare PtrSafe Function GetDlgItem Lib "user32" ( _
ByVal hDlg As LongPtr, _
ByVal nIDDlgItem As Long _
) As LongPtr
Private Declare PtrSafe Function SendMessage Lib "user32" _
Alias "SendMessageA" ( _
ByVal hwnd As LongPtr, _
ByVal wMsg As Long, _
ByVal wParam As LongPtr, _
lParam As Any _
) As LongPtr
Private Function ProcIDFromWnd(ByVal hwnd As LongPtr) As Long
Dim idProc As Long
GetWindowThreadProcessId hwnd, idProc
ProcIDFromWnd = idProc
End Function
Private Function GetWinHandleProc(ByVal tmpHwnd As LongPtr, _
ByVal lParam As Long _
) As Boolean
If lParam = ProcIDFromWnd(tmpHwnd) Then
Dim wText As String, wTextLength As Long
wText = String(255, Chr(0))
wTextLength = GetWindowText(tmpHwnd, wText, 255)
If "Microsoft Access" = Left(wText, wTextLength) Then
pHwnd = tmpHwnd
GetWinHandleProc = False
Exit Function
End If
End If
GetWinHandleProc = True
End Function
'Private Function GetWinHandleProc(ByVal tmpHwnd As LongPtr, _
' ByRef lParam As UserDefined01 _
' ) As Boolean
' If lParam.taskID = ProcIDFromWnd(tmpHwnd) Then
' Dim wText As String, wTextLength As Long
' wText = String(255, Chr(0))
' wTextLength = GetWindowText(tmpHwnd, wText, 255)
' If "Microsoft Access" = Left(wText, wTextLength) Then
' lParam.Hwnd = tmpHwnd
' GetWinHandleProc = False
' Exit Function
' End If
' End If
' GetWinHandleProc = True
'End Function
Private Function GetWinHandle(taskID As Long) As LongPtr
pHwnd = 0
EnumWindows AddressOf GetWinHandleProc, taskID
GetWinHandle = pHwnd
End Function
'Private Function GetWinHandle(taskID As Long) As LongPtr
' Dim tmp As UserDefined01
' tmp.taskID = taskID
' tmp.Hwnd = 0
' EnumWindows AddressOf GetWinHandleProc, tmp
' GetWinHandle = tmp.Hwnd
'End Function
Sub OpenAccdrWithPassword( _
targetDBFullPath As String, _
pswd As String, _
Optional WindowStyle As VbAppWinStyle = vbNormalFocus)
Dim taskID As Long
Dim targetDBHwnd As LongPtr
Dim pswdDlgHwnd As LongPtr
Dim dlgEditHwnd As LongPtr, dlgButtonOKHwnd As LongPtr
If Dir(targetDBFullPath) = "" Then Exit Sub
taskID = Shell("msaccess.exe /runtime " & _
targetDBFullPath, _
WindowStyle)
If taskID = 0 Then Exit Sub
'この部分たまたま動作しているのではないか?
targetDBHwnd = GetWinHandle(taskID)
Do
pswdDlgHwnd = GetLastActivePopup(targetDBHwnd)
Loop While targetDBHwnd = pswdDlgHwnd
dlgEditHwnd = GetDlgItem(pswdDlgHwnd, IDC_EDIT)
dlgButtonOKHwnd = GetDlgItem(pswdDlgHwnd, IDOK)
SendMessage dlgEditHwnd, WM_SETTEXT, 0, ByVal pswd
SendMessage dlgButtonOKHwnd, BM_CLICK, 0, 0
End Sub
ラベル:
access 2010,
API,
Office 2010,
VBA
office2010 Win32API GetDlgItem/GetLastActivePopup
Option Compare Database
Option Explicit
Private Const GW_HWNDNEXT = &H2
Private Const WM_SETTEXT = &HC
Private Const BM_CLICK = &HF5
Private Const IDOK = &H1
Private Const IDCANCEL = &H2
Private Const IDHELP = &H9
Private Const IDC_EDIT = &H8A5 '決め打ち
'http://msdn.microsoft.com/ja-jp/library/cc364779.aspx
Private Declare PtrSafe Function GetWindowThreadProcessId Lib "user32" ( _
ByVal hwnd As LongPtr, _
lpdwProcessId As Long _
) As Long
'http://msdn.microsoft.com/ja-jp/library/cc364757.aspx
Private Declare PtrSafe Function GetWindow Lib "user32" ( _
ByVal hwnd As LongPtr, _
ByVal wCmd As Long _
) As LongPtr
'http://msdn.microsoft.com/ja-jp/library/cc364718.aspx
Private Declare PtrSafe Function GetParent Lib "user32" ( _
ByVal hwnd As LongPtr _
) As LongPtr
Private Declare PtrSafe Function FindWindow Lib "user32" _
Alias "FindWindowA" ( _
ByVal lpClassName As String, _
ByVal lpWindowName As String _
) As LongPtr
'http://msdn.microsoft.com/ja-jp/library/cc364701.aspx
Private Declare PtrSafe Function GetLastActivePopup Lib "user32" ( _
ByVal hwndOwnder As LongPtr _
) As LongPtr
'http://msdn.microsoft.com/ja-jp/library/cc364621.aspx
Private Declare PtrSafe Function GetDlgItem Lib "user32" ( _
ByVal hDlg As LongPtr, _
ByVal nIDDlgItem As Long _
) As LongPtr
Private Declare PtrSafe Function SendMessage Lib "user32" _
Alias "SendMessageA" ( _
ByVal hwnd As LongPtr, _
ByVal wMsg As Long, _
ByVal wParam As LongPtr, _
lParam As Any _
) As LongPtr
'http://support.microsoft.com/kb/242308/ja
'EnumWindows
Private Function ProcIDFromWnd(ByVal hwnd As LongPtr) As Long
Dim idProc As Long
' Get PID for this HWnd
GetWindowThreadProcessId hwnd, idProc
' Return PID
ProcIDFromWnd = idProc
End Function
Private Function GetWinHandle(hInstance As Long) As LongPtr
Dim tempHwnd As LongPtr
' Grab the first window handle that Windows finds:
tempHwnd = FindWindow(vbNullString, vbNullString)
' Loop until you find a match or there are no more window handles:
Do Until tempHwnd = 0
' Check if no parent for this window
If GetParent(tempHwnd) = 0 Then
' Check for PID match
If hInstance = ProcIDFromWnd(tempHwnd) Then
' Return found handle
GetWinHandle = tempHwnd
' Exit search loop
Exit Do
End If
End If
' Get the next window handle
tempHwnd = GetWindow(tempHwnd, GW_HWNDNEXT)
Loop
End Function
Sub OpenAccdrWithPassword( _
targetDBFullPath As String, _
pswd As String, _
Optional WindowStyle As VbAppWinStyle = vbNormalFocus)
Dim taskID As Long
Dim targetDBHwnd As LongPtr
Dim pswdDlgHwnd As LongPtr
Dim dlgEditHwnd As LongPtr, dlgButtonOKHwnd As LongPtr
If Dir(targetDBFullPath) = "" Then Exit Sub
taskID = Shell("msaccess.exe /runtime " & _
targetDBFullPath, _
WindowStyle)
'hInstanceなのか?
targetDBHwnd = GetWinHandle(taskID)
Do
pswdDlgHwnd = GetLastActivePopup(targetDBHwnd)
Loop While targetDBHwnd = pswdDlgHwnd
dlgEditHwnd = GetDlgItem(pswdDlgHwnd, IDC_EDIT)
dlgButtonOKHwnd = GetDlgItem(pswdDlgHwnd, IDOK)
SendMessage dlgEditHwnd, WM_SETTEXT, 0, ByVal pswd
SendMessage dlgButtonOKHwnd, BM_CLICK, 0, 0
End Sub
ラベル:
access 2010,
API,
Office 2010,
VBA
2010/12/26
access2010 access2007 Win32API レジストリ その2
Option Compare Database
Option Explicit
Private Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(7) As Byte
End Type
Private Const HKEY_CURRENT_USER = &H80000001
Private Const ERROR_SUCCESS = 0
Private Const REG_SZ = 1 ' Unicode nul terminated string
Private Const REG_DWORD = 4 '32-bit number
Private Const REG_OPTION_NON_VOLATILE = 0
Private Const KEY_ALL_ACCESS = &HF003F
Private Const KEY_SET_VALUE = &H2
#If VBA7 Then
Private Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As LongPtr
bInheritHandle As Long
End Type
Private Const strTrustedLocations = "Software\Microsoft\Office\14.0\Access\Security\Trusted Locations\"
Private Declare PtrSafe Function RegCreateKeyEx Lib "advapi32.dll" _
Alias "RegCreateKeyExA" ( _
ByVal hKey As LongPtr, _
ByVal lpSubKey As String, _
ByVal Reserved As Long, _
ByVal lpClass As String, _
ByVal dwOptions As Long, _
ByVal samDesired As Long, _
lpSecurityAttributes As SECURITY_ATTRIBUTES, _
phkResult As LongPtr, _
lpdwDisposition As Long _
) As Long
Private Declare PtrSafe Function RegSetValueEx Lib "advapi32.dll" _
Alias "RegSetValueExA" ( _
ByVal hKey As LongPtr, _
ByVal lpValueName As String, _
ByVal Reserved As Long, _
ByVal dwType As Long, _
lpData As Any, _
ByVal cbData As Long _
) As Long
Private Declare PtrSafe Function RegCloseKey Lib "advapi32.dll" ( _
ByVal hKey As LongPtr _
) As Long
Private Declare PtrSafe Function CoCreateGuid Lib "OLE32.DLL" ( _
pGuid As GUID _
) As Long
#Else
Private Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As Long
bInheritHandle As Long
End Type
Private Const strTrustedLocations = "Software\Microsoft\Office\12.0\Access\Security\Trusted Locations\"
Private Declare Function RegCreateKeyEx Lib "advapi32.dll" _
Alias "RegCreateKeyExA" ( _
ByVal hKey As Long, _
ByVal lpSubKey As String, _
ByVal Reserved As Long, _
ByVal lpClass As String, _
ByVal dwOptions As Long, _
ByVal samDesired As Long, _
lpSecurityAttributes As SECURITY_ATTRIBUTES, _
phkResult As Long, _
lpdwDisposition As Long _
) As Long
Private Declare Function RegSetValueEx Lib "advapi32.dll" _
Alias "RegSetValueExA" ( _
ByVal hKey As Long, _
ByVal lpValueName As String, _
ByVal Reserved As Long, _
ByVal dwType As Long, _
lpData As Any, _
ByVal cbData As Long _
) As Long
Private Declare Function RegCloseKey Lib "advapi32.dll" ( _
ByVal hKey As Long _
) As Long
Private Declare Function CoCreateGuid Lib "OLE32.DLL" ( _
pGuid As GUID _
) As Long
#End If
Public Function GetNewGUID() As String
Dim udtGUID As GUID
If (CoCreateGuid(udtGUID) = 0) Then
GetNewGUID = "{" & _
String(8 - Len(Hex$(udtGUID.Data1)), "0") & Hex$(udtGUID.Data1) & "-" & _
String(4 - Len(Hex$(udtGUID.Data2)), "0") & Hex$(udtGUID.Data2) & "-" & _
String(4 - Len(Hex$(udtGUID.Data3)), "0") & Hex$(udtGUID.Data3) & "-" & _
IIf((udtGUID.Data4(0) < &H10), "0", "") & Hex$(udtGUID.Data4(0)) & _
IIf((udtGUID.Data4(1) < &H10), "0", "") & Hex$(udtGUID.Data4(1)) & "-" & _
IIf((udtGUID.Data4(2) < &H10), "0", "") & Hex$(udtGUID.Data4(2)) & _
IIf((udtGUID.Data4(3) < &H10), "0", "") & Hex$(udtGUID.Data4(3)) & _
IIf((udtGUID.Data4(4) < &H10), "0", "") & Hex$(udtGUID.Data4(4)) & _
IIf((udtGUID.Data4(5) < &H10), "0", "") & Hex$(udtGUID.Data4(5)) & _
IIf((udtGUID.Data4(6) < &H10), "0", "") & Hex$(udtGUID.Data4(6)) & _
IIf((udtGUID.Data4(7) < &H10), "0", "") & Hex$(udtGUID.Data4(7)) & "}"
End If
End Function
Sub setTrustedLocations()
#If VBA7 Then
Dim hNewKey As LongPtr
#Else
Dim hNewKey As Long
#End If
Dim lngrtn As Long, strSubKey As String
Dim SA As SECURITY_ATTRIBUTES, rtnDisp As Long
Dim strValue As String, lngValue As Long
strSubKey = strTrustedLocations & GetNewGUID
lngrtn = RegCreateKeyEx(HKEY_CURRENT_USER, _
strSubKey, _
0, _
vbNullString, _
REG_OPTION_NON_VOLATILE, _
KEY_ALL_ACCESS, _
SA, _
hNewKey, _
rtnDisp)
If lngrtn = ERROR_SUCCESS Then
strValue = CurrentProject.Path & "\"
RegSetValueEx hNewKey, _
"Path", _
0, _
REG_SZ, _
ByVal strValue, _
LenB(strValue)
strValue = CurrentProject.Name & "の自炊レジストリ"
RegSetValueEx hNewKey, _
"Description", _
0, _
REG_SZ, _
ByVal strValue, _
LenB(strValue)
strValue = Format(Now, "yyyy/mm/dd hh:nn")
RegSetValueEx hNewKey, _
"Date", _
0, _
REG_SZ, _
ByVal strValue, _
LenB(strValue)
' lngValue = 1
' RegSetValueEx hNewKey, _
' "AllowSubfolders", _
' 0, _
' REG_DWORD, _
' lngValue, _
' Len(lngValue)
End If
RegCloseKey hNewKey
End Sub
ラベル:
access 2010,
API,
MS-Access,
VBA
2010/12/24
access2010 Quick Access Display(仮)
これの制御方法がわかんない。accessのオプションなんだけど、
Application.SetOption "Size of MRU File List", 0 じゃないんだよな。そもそも、Size of MRU File List 使えてないみたいだし。
[クライアントの設定]→[表示]→[最近使用した...]の設定は、
キー名:HKEY_CURRENT_USER\Software\Microsoft\Office\14.0\Access\File MRU
名前:Max Display
で、backstageから投入するのは、
名前:Max Quick Access Display
に入ってるしな。SetOptionメソッドで設定する方法が不明だから、そのうちにでも。
で、本題のショートカットの件。
キー名:HKEY_CURRENT_USER\Software\Microsoft\Office\14.0\Access\File MRU
名前:Quick Access Display
に情報がある。 レジストリを直接いじればなんとか。
[カレントデータベース]→[リボンとツールバーのオプション]→[すべてのメニューを表示する]で非表示にする。だけど、この場合、セパレータが残る。
CustomUI/backstage要素内で制御する方法はなさそう。
Application.SetOption "Size of MRU File List", 0 じゃないんだよな。そもそも、Size of MRU File List 使えてないみたいだし。
[クライアントの設定]→[表示]→[最近使用した...]の設定は、
キー名:HKEY_CURRENT_USER\Software\Microsoft\Office\14.0\Access\File MRU
名前:Max Display
で、backstageから投入するのは、
名前:Max Quick Access Display
に入ってるしな。SetOptionメソッドで設定する方法が不明だから、そのうちにでも。
で、本題のショートカットの件。
キー名:HKEY_CURRENT_USER\Software\Microsoft\Office\14.0\Access\File MRU
名前:Quick Access Display
に情報がある。 レジストリを直接いじればなんとか。
Sub setQuickAccessDisplay()
Dim kHnd As LongPtr, lngvalue As Long, lngrtn As Long
lngvalue = 0 '0:非表示 1:表示
Const strSubKey = "Software\Microsoft\Office\14.0\Access\File MRU"
Const strName = "Quick Access Display"
lngrtn = RegOpenKeyEx(HKEY_CURRENT_USER, strSubKey, 0, KEY_SET_VALUE, kHnd)
If lngrtn = ERROR_SUCCESS Then
RegSetValueEx kHnd, strName, 0, REG_DWORD, lngvalue, Len(lngvalue)
End If
RegCloseKey kHnd
End Sub
もしくは、[カレントデータベース]→[リボンとツールバーのオプション]→[すべてのメニューを表示する]で非表示にする。だけど、この場合、セパレータが残る。
CustomUI/backstage要素内で制御する方法はなさそう。
ラベル:
access 2010,
API,
RibbonUI,
VBA
office2010 Win32API レジストリ
Option Compare Database
Option Explicit
Private Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As LongPtr
bInheritHandle As Long
End Type
Private Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type
Private Const HKEY_CURRENT_USER = &H80000001
Private Const HKEY_LOCAL_MACHINE = &H80000002
Private Const ERROR_SUCCESS = 0
Private Const REG_SZ = 1 ' Unicode nul terminated string
Private Const REG_DWORD = 4 '32-bit number
Private Const REG_OPTION_NON_VOLATILE = 0
Private Const KEY_ALL_ACCESS = &HF003F
Private Const KEY_SET_VALUE = &H2
Private Const KEY_QUERY_VALUE = &H1
Private Declare PtrSafe Function RegCreateKeyEx Lib "advapi32.dll" _
Alias "RegCreateKeyExA" ( _
ByVal hKey As LongPtr, _
ByVal lpSubKey As String, _
ByVal Reserved As Long, _
ByVal lpClass As String, _
ByVal dwOptions As Long, _
ByVal samDesired As Long, _
lpSecurityAttributes As SECURITY_ATTRIBUTES, _
phkResult As LongPtr, _
lpdwDisposition As Long _
) As Long
Private Declare PtrSafe Function RegOpenKeyEx Lib "advapi32.dll" _
Alias "RegOpenKeyExA" ( _
ByVal hKey As LongPtr, _
ByVal lpSubKey As String, _
ByVal ulOptions As Long, _
ByVal samDesired As Long, _
phkResult As LongPtr _
) As Long
' Note that if you declare the lpData parameter as String, you must pass it By Value.
' RegQueryValueEx kHnd, strName, 0, 0, ByVal strBuffer, Len(strBuffer)
Private Declare PtrSafe Function RegQueryValueEx Lib "advapi32.dll" _
Alias "RegQueryValueExA" ( _
ByVal hKey As LongPtr, _
ByVal lpValueName As String, _
ByVal lpReserved As LongPtr, _
lpType As Long, _
lpData As Any, _
lpcbData As Long _
) As Long
' Note that if you declare the lpData parameter as String, you must pass it By Value.
' RegSetValueEx kHnd, strName, 0, REG_SZ, ByVal strValue, Len(strValue)
Private Declare PtrSafe Function RegSetValueEx Lib "advapi32.dll" _
Alias "RegSetValueExA" ( _
ByVal hKey As LongPtr, _
ByVal lpValueName As String, _
ByVal Reserved As Long, _
ByVal dwType As Long, _
lpData As Any, _
ByVal cbData As Long _
) As Long
Private Declare PtrSafe Function RegDeleteKey Lib "advapi32.dll" _
Alias "RegDeleteKeyA" ( _
ByVal hKey As LongPtr, _
ByVal lpSubKey As String _
) As Long
Private Declare PtrSafe Function RegDeleteValue Lib "advapi32.dll" _
Alias "RegDeleteValueA" ( _
ByVal hKey As LongPtr, _
ByVal lpValueName As String _
) As Long
Private Declare PtrSafe Function RegCloseKey Lib "advapi32.dll" ( _
ByVal hKey As LongPtr _
) As Long
Private Declare PtrSafe Function RegQueryInfoKey Lib "advapi32.dll" _
Alias "RegQueryInfoKeyA" ( _
ByVal hKey As LongPtr, _
ByVal lpClass As String, _
lpcbClass As Long, _
ByVal lpReserved As LongPtr, _
lpcSubKeys As Long, _
lpcbMaxSubKeyLen As Long, _
lpcbMaxClassLen As Long, _
lpcValues As Long, _
lpcbMaxValueNameLen As Long, _
lpcbMaxValueLen As Long, _
lpcbSecurityDescriptor As Long, _
lpftLastWriteTime As FILETIME _
) As Long
Private Declare PtrSafe Function RegEnumKeyEx Lib "advapi32.dll" _
Alias "RegEnumKeyExA" ( _
ByVal hKey As LongPtr, _
ByVal dwIndex As Long, _
ByVal lpName As String, _
lpcbName As Long, _
ByVal lpReserved As LongPtr, _
ByVal lpClass As String, _
lpcbClass As Long, _
lpftLastWriteTime As FILETIME _
) As Long
Private Declare PtrSafe Function RegEnumValue Lib "advapi32.dll" _
Alias "RegEnumValueA" ( _
ByVal hKey As LongPtr, _
ByVal dwIndex As Long, _
ByVal lpValueName As String, _
lpcbValueName As Long, _
ByVal lpReserved As LongPtr, _
lpType As Long, lpData As Byte, _
lpcbData As Long _
) As Long
ラベル:
access 2010,
API,
Office 2010,
VBA
2010/12/13
office2010 Win32API keybd_event Backstageを表示させない
access2010でファイルタブ押下してもBackstageを表示させない。といっても、onShowでESCキー押下しているだけ。
SendInputを使うよりは、keybd_eventの方が64bit対応がすっきりしてていいかなということだけ。まぁとりあえず作動するし。
Option Compare Database
Option Explicit
Private Const VK_ESCAPE = &H1B
Private Const KEYEVENTF_KEYUP = &H2
Private Const KEYEVENTF_EXTENDEDKEY = &H1
'http://msdn.microsoft.com/ja-jp/library/cc364822.aspx
'SendInputを使えとなってるけど、別途x64対応せにゃならんからこっち使う。
Private Declare PtrSafe Sub keybd_event Lib "user32" ( _
ByVal bVk As Byte, _
ByVal bScan As Byte, _
ByVal dwFlags As Long, _
ByVal dwExtraInfo As LongPtr)
Sub onShow(cntxt As Object)
keybd_event VK_ESCAPE, 0, 0, 0
keybd_event VK_ESCAPE, 0, KEYEVENTF_KEYUP, 0
End Sub
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui"> <backstage onShow="onShow" /> </customUI>なのだけど、結局ribbonXmlを書かにゃならん。
SendInputを使うよりは、keybd_eventの方が64bit対応がすっきりしてていいかなということだけ。まぁとりあえず作動するし。
ラベル:
access 2010,
API,
Office 2010,
RibbonUI,
VBA
登録:
投稿 (Atom)