Hi all I'm trying to find a function in winapi manual that allows me to test if my program has uiAccess true or not, is there such a function?
Related
Is it safe to call XGetErrorText from a error handler set by XSetErrorHandler?
E.g.
int errorHandler(Display *dpy, XErrorEvent *err)
{
char buf[BUFLEN];
XGetErrorText(dpy, err->error_code, buf, BUFLEN);
printf("%s\n", buf)
return 0;
}
XSetErrorHandler(errorHandler);
I'm asking because the man page says you should not call any functions (directly or indirectly) on the display that will generate protocol requests but it does not tell if XGetErrorText does.
XGetErrorText doesn't generate any server traffic. It's not supposed to: the server doesn't know your locale, for example, and cannot supply localised messages. XLib can, and indeed does with a couple of local Xrm database lookups.
The source code of XGetErrorText can be viewed e.g. here. We can see that XGetErrorText calls XGetErrorDatabaseText, and this latter function is not even using its dpy parameter.
Each X extension provides its own error-event-to-error-string translation function. This function does accept a dpy parameter, but, just like XGetErrorDatabaseText is not supposed to use it too generate any server traffic. This error-handling function is by default generateed by the XEXT_GENERATE_ERROR_STRING macro here, which just encapsulates another call to XGetErrorDatabaseText.
I'm adding a call to the SetProcessDpiAwareness windows function as the first thing in my Delphi XE7 application (after dynamically loading the shcore DLL). I know it is preferable to use a manifest to set the DPIAware value and I've got that working separately and will use it eventually. However during development I want to use a command line parameter to set DPIAwareness value, otherwise I have to rebuild the app to change this status.
The problem is that SetProcessDpiAwareness returns the error code $800700A0.
That is not documented in the function description, what does the code mean?
Ah I've found it, thanks to the answer to look at the parameter, I had declared the function type wrong, I had:
TSetDPIFunc = function (const PROCESS_DPI_AWARENESS) : HRESULT; stdcall;
but PROCESS_DPI_AWARENESS was not defined as an enum.
Changed to the following and it now works fine:
TSetDPIFunc = function (const x: Integer) : HRESULT; stdcall;
0x8007XXXX is a Win32 error code encapsulated in a COM HRESULT using HRESULT_FROM_WIN32(). WIN32_FROM_HRESULT(0x800700A0) gives 0xA0, i.e. error code 160, which is ERROR_BAD_ARGUMENTS ("One or more of the input parameters are not correct").
It makes no sense for me though that you get this error, since this function doesn't even take any arguments!
So the only thing I can think of would be that it has something to with the issue described here, assuming you changed the DPI settings yourself for testing and it failed then:
So it seems that in order for SetProcessDPIAware (and the related approaches: SetProcessDpiAwareness() and manifest with true) to work correctly, one has to log out and login again after changing the DPI setting and before running the program.
By the way, in case this is helpful: For testing manifests without totally rebuilding, you could use mt.exe to attach a manifest to your application from the command line.
CopyFileEx with a following call to GetLastError returns ERROR_INVALID_PARAMETER even if the copy is successful on Win2012R2 since around 2 months back (maybe from December 2015). On Windows XP till Windows 7 and Win 2k3 till Win2k8R2 this does not happen and GetLastError always returns 0 (ERROR_SUCCESS).
Is this expected behavior of this kind of Win32 API?
Do you have to add both result and GetLastError code be sure of the result?
This KB seems related to the problem but applying this patch does not alter the API behavior. There was probably another KB that caused the problem to appear but I have been unable to find it
https://support.microsoft.com/en-us/kb/2963918
Documentation for GetLastError:
Return value
The return value is the calling thread's last-error code.
The Return Value section of the documentation for each function that
sets the last-error code notes the conditions under which the function
sets the last-error code. Most functions that set the thread's
last-error code set it when they fail. However, some functions also
set the last-error code when they succeed. If the function is not
documented to set the last-error code, the value returned by this
function is simply the most recent last-error code to have been set;
some functions set the last-error code to 0 on success and others do
not.
From the documentation:
Return value
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. To get extended error
information call GetLastError.
In other words, if the function succeeds, you are not expected to call GetLastError, and no promise is made about what will be returned if you do.
So, you are ascribing meaning to the value returned by GetLastError where no meaning should be ascribed.
This is a common pattern in Win32. A great many functions are similar. The value returned by GetLastError is only meaningful in the event that the return value of the function indicates failure. That is not a universal rule though, so you do need to check the documentation on a function by function basis.
The typical form of a call to such a Win32 function looks like this:
if (CopyFileEx(...))
{
// function call succeeded, continue
}
else
{
DWORD err = GetLastError();
// do something with err
}
Note that GetLastError is only called if the function indicates failure through its return value.
Is it OK to initialize the Win32 HANDLE to NULL? Or are there any better or recommended way to initialize HANDLEs?
For example,
void foo()
{
HANDLE hFile;
hFile = CreateFile(/* necessary arguments*/);
}
What shall i initialize the hFile with?
In your example code you don't need to initialise hFile to anything since it is initialised by the CreateFile function.
The Windows API is not completely consistent on what it considers a "null" handle. Some APIs (like CreateFile) return INVALID_HANDLE_VALUE on failure, whereas others return NULL on failure. So the way you test if a HANDLE is valid or not depends on the function you are getting it from - check the actual documentation for the function and see what it says is the return value on failure.
I want to simulate WindowsKey + L (The short cut to lock the console) in visual basic and bind it to a function. So when this function is called it will lock the console.
Can I do this?
Simulating the hotkey is the wrong approach. All you need to do is call the LockWorkStation function. This has the same result as pressing Ctrl+Alt+Del and selecting "Lock Workstation", or using the Win+L hotkey, except that you can do it programmatically through code.
To call this function from a VB application, you'll need to write a declaration, like so:
Private Declare Function LockWorkStation Lib "user32.dll" () As Long
You'll want to place that declaration at the top of your module file, before any procedures are defined. Then, inside one of the procedures, you can call the function. For example:
Private Sub LockComputer()
LockWorkStation
End Sub
Even better code would check the return value of LockWorkStation for an error code. A return value of 0 indicates an error. The standard way of checking for Win32 errors in VB, Err.LastDllError, will give you more information about what exactly went wrong.