在我的旧shellapi.pas(32位)中未指定MSDN中指定的SHQueryUserNotificationState
函数。此功能在Vista中引入。在网上搜索找到Pascal实现但是找不到它。
在C ++(MSDN)中:
HRESULT SHQueryUserNotificationState(
_Out_ QUERY_USER_NOTIFICATION_STATE *pquns
);
和
typedef enum {
QUNS_NOT_PRESENT = 1,
QUNS_BUSY = 2,
QUNS_RUNNING_D3D_FULL_SCREEN = 3,
QUNS_PRESENTATION_MODE = 4,
QUNS_ACCEPTS_NOTIFICATIONS = 5,
QUNS_QUIET_TIME = 6,
QUNS_APP = 7
} QUERY_USER_NOTIFICATION_STATE;
我已经拥有的东西(pascal 32bit):
function SHQueryUserNotificationState( p : Pointer ) : HRESULT; stdcall; external shell32 name 'SHQueryUserNotificationState';
代码来调用它:
var
i : LongInt;
begin
if( SHQueryUserNotificationState( @i ) = S_OK ) then
begin
writeln( i );
end;
end;
这是完美的工作(返回预期的值),但我想知道指针的类型。它似乎是一个32位变量的指针,但想知道这是否正确(签名/未签名),以避免其他Windows操作系统/系统(现在在Windows 7 64位上运行)的问题,我想知道它是当然。有人能告诉我这个函数的正确实现吗?
MSDN上的功能说明: https://msdn.microsoft.com/en-us/library/windows/desktop/bb762242%28v=vs.85%29.aspx
编辑:指向DWORD的指针?
//////////////////以下不是问题的一部分///////////////
EDIT2 :(示例)我制作的代码
因为它要求应用程序可以在低于Vista的操作系统上运行(并且并不总是需要),所以我使该功能可选(动态分配)。根据接受的答案,这是最终结果:
........
type
// See also: https://msdn.microsoft.com/en-us/library/windows/desktop/bb762533%28v=vs.85%29.aspx
TUserNotifcationState = (unsError, // -. Cannot not obtain info, mostly error running on Windows lower than Vista
unsUnknown, // -. Working, but unknown future feature value returned by WinAPI func.
unsNotPresent, // 1. User not present, screensave active or fast user switch in progress
unsFullScreen, // 2. Windows run an application in full screen mode
unsDirectX, // 3. A full screen Direct3D/DirectX is running
unsPresentation, // 4. Activated presentation and blocks notification and popup messages
unsNormal, // 5. User runs Windows normally, accept messages and popup messages
unsPresentLocked, // 6. Windows 7 and higher, present but logging in
unsWindowsStoreApp // 7. Windows 8 and higher, user runs Windows Store app (metro app)
);
TUserNotificationStateFunc = function( var iResult : Integer ) : HRESULT; stdcall;
.............
const
FShell32Handle : THandle = 0;
.............
function shellGetUserNoticationState() : TUserNotifcationState;
const
fFunc : TUserNotificationStateFunc = nil;
bErr : Boolean = FALSE;
var
cResult : Integer;
begin
Result:=unsError;
if( bErr ) then
Exit;
if( NOT Assigned( fFunc )) then
begin
if( FShell32Handle < 0 ) then
Exit;
if( FShell32Handle = 0 ) then
begin
FShell32Handle:=LoadLibrary( shell32 );
bErr:=( FShell32Handle <= 0 );
if( bErr ) then
Exit;
end;
try
fFunc:=getProcAddress( FShell32Handle, 'SHQueryUserNotificationState' );
except
bErr:=TRUE;
end;
bErr:=(( bErr ) or ( NOT Assigned( fFunc )));
end;
if( NOT bErr ) then
begin
cResult:=high( Cardinal ); // set to abnormal range
try
bErr:=( fFunc( cResult ) <> S_OK );
except
bErr:=TRUE;
end;
end;
if( bErr ) or ( cResult < 1 ) or ( cResult >= 50 {50 = future options, but not supported in this compile} ) then
Exit;
// Future options higher than latest Win8 additions not supported
// in this compile.
if( cResult > 7 ) then
begin
Result:=unsUnknown;
Exit;
end;
Result:=TUserNotifcationState( Byte( cResult )+1 );
end;
.............
initialization
finalization
if( FShell32Handle > 0 ) then
FreeLibrary( FShell32Handle );
end.
由于动态调用Windows API函数,因此当DLL中不存在API函数时,应用程序将始终运行并且不会中断。 在低于Vista的OS上运行代码时,该函数始终返回unsError。在高于Windows 8或更新版本的操作系统上运行代码并添加操作系统中的新枚举值时,它将返回unsUnknown。
答案 0 :(得分:4)
Delphi XE4中此API的声明声明该参数是指向整数的指针(实际上,整数> 整数 >,这相同的事情。)
声明不直接使用整数,但声明为所涉及的枚举命名的类型别名:
type
QUERY_USER_NOTIFICATION_STATE = Integer;
function SHQueryUserNotificationState(var pquns: QUERY_USER_NOTIFICATION_STATE): HResult; stdcall;
枚举(在C / C ++中)的实际大小就我所知,并且依赖于实现&#39;在这种情况下,相关的实现是Windows API。据我所知,这意味着整数,这与Delphi XE4声明一致。这是否意味着Windows API中的所有枚举保证大小为整数或不...我想是的。
无论如何,在这种特定情况下,Delphi XE4 API头是在参数是对 Integer (32位有符号整数)的引用的基础上声明的。
您使用 LongInt 与使用整数完全相同。但是,根据Delphi XE4声明,我将消除使用无类型指针并使用正确键入的 out 或 var 参数。
RE:DWORD?
DWORD 类型相当于 Cardinal (无符号32位整数)。
由于这正式是一个 out 参数(表示API不会使用通过此参数传递给它的任何值),这是API的重要内容。我们的观点是你提供了一个指向正确大小的变量的指针供它写入(这就是为什么无类型指针是个坏主意)。在这种情况下,32位。那么你如何解释那些32位的API在你的位置。
在这种情况下,由于枚举没有签名值且所有涉及的值(轻松地)在整数的正范围内,您可以使用整数或 Cardinal 与您的应用程序代码的角度没有任何明显的区别。
然而,对于我希望的显而易见的原因,我会坚持正式的类型。 :)
警告开发者: Delphi API翻译并不总是100%可靠,但除非并且直到证明其他方式,它们至少是一个良好的起点,我没有理由认为这是错误的