This is a sample piece of code showing the problem. I need to use the PostMessage function but i can't seem to get the symbol recognised. I've created a simple program to opening a win32 window which works fine but when i use either PostMessage or UnregisterClass they don't seem to be defined. I've check the D source and they are there but why does the compiler complain? I tried using the ascii and wide versions too.
import std.c.windows.windows;
extern(Windows):
void main(string[] Args)
{
PostMessage(0, WM_CLOSE, 0, 0);
PostMessageA(0, WM_CLOSE, 0, 0);
PostMessageW(0, WM_CLOSE, 0, 0);
}
Output:
Error: undefined identifier PostMessage
Error: undefined identifier PostMessageA
Error: undefined identifier PostMessageW
How can i use this function call in a D program?
std.c.windows.windows is very incomplete. Use the WindowsApi bindings project, instead.
Related
In an android native application, when I call:
vkDestroyDevice( vk.device, VK_ALLOCATOR )
I've got error Error: [Validation] Code 614466292 X object 0xffffffffd3bcb900 has not been destroyed (...).
But I have called vkDestroy(Object) for each of the objects. (image, imageview, pipeline, etc)
Here is one object creation / destruction:
static void create_shader_module(const unsigned char* pBytes, const int count, VkShaderModule* pVkShaderMod) {
VkShaderModuleCreateInfo desc;
desc.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
desc.pNext = NULL;
desc.flags = 0;
desc.codeSize = count;
desc.pCode = (const uint32_t*)pBytes;
VK(vkCreateShaderModule(vk.device, &desc, NULL, pVkShaderMod));
}
extern unsigned char multiview_single_texture_vert_spv[];
extern int multiview_single_texture_vert_spv_size;
create_shader_module(multiview_single_texture_vert_spv, multiview_single_texture_vert_spv_size, &s_gShaderModules.single_texture_vs);
And for the destruction part:
vkDestroyShaderModule(vk.device, s_gShaderModules.single_texture_vs, NULL);
When I call vkDestroyShaderModule, vk.device is still active, and I 've got no error.
But as soon as I call vkDestroyDevice(), I've got error:
OBJ ERROR : For device 0xeb0ac330, ShaderModule object
0xffffffffeb0c6240 has not been destroyed. The spec valid usage text
states 'All child objects created on device must have been destroyed
prior to destroying device'
Freeing the struct memory with memset(&s_gShaderModules, 0, sizeof(s_gShaderModules)); does not solve the problem.
The error is on an android device, unfortunaly I can't test the application on another device.
Everything else in the application works, I even destruct and recreate some of the objects at runtime without error, except the application crash on exit.
I've just removed the validation layers, and surprisingly the application no longer crashes, the closing sequence ends successfully. Why didn't I try it earlier?
The problem only occurs with layers, it may be due to their order in the extension array.
We have a minimal working example of dlopen that works.
void* lib = dlopen("servlets.so", RTLD_NOW);
void* p = dlsym(lib, "getServlets");
However, if we add another function to the shared library (not even if it is called) then the library does not work (even though the code is never called)
uint32_t count = 0;
Servlet** servlets;
extern "C" {
void generate() {
servlets = new Servlet*[3];
servlets[0] = new Servlet(...);
}
Servlet** getServlets() { return servlets; }
uint32_t getServletNum() { return count; }
}
This must be because the code in the shared object is referencing some symbol that we don't have, but we do not know what.
The code compiles and links without a problem.
Is there any way to find out what the error is? No error is reported, except that the library pointer returns NULL and the library does not load.
How do we link to a library so that dlopen works?
No error is reported, except that the library pointer returns NULL
A library pointer can't return anything. You probably mean dlopen() returns NULL.
If that's what you mean, that is the error being reported. If you want to know more about why the error was returned, use dlerror() to find out.
Reading the documentation it looks like the ShowWindow function has no notion of failure. This surprises me since it seems that pretty much any non-trivial code can fail.
The window handle might be invalid. Clearly, that's a contact violation committed by the caller but is this case simply "undefined" or "don't care", then?
I wonder if SetLastError is supported.
While ShowWindow() indeed has no notion of error, we can use SetWindowPos() as an alternative that is documented to support GetLastError().
In the following I provide an example that shows how to wrap SetWindowPos() into a function to bridge the gap between C-style error reporting and the C++ way of doing it by throwing and handling an exception.
Example:
#include <windows.h>
#include <iostream>
#include <sstream>
#include <system_error>
// Show or hide the given window by calling SetWindowPos().
//
// \exception Reports any error by throwing std::sytem_error exception.
void MyShowWindow( HWND hwnd, bool show ) {
DWORD flags = SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER;
if( show )
flags |= SWP_SHOWWINDOW;
else
flags |= SWP_HIDEWINDOW;
if( !::SetWindowPos( hwnd, nullptr, 0, 0, 0, 0, flags ) ) {
// NOTE: Call GetLastError() IMMEDIATELY when a function's return value indicates
// failure and it is documented that said function supports GetLastError().
// ANY other code (be it your own or library code) before the next line must be
// avoided as it may invalidate the last error value.
DWORD err = ::GetLastError();
std::ostringstream msg;
msg << "Could not change visibility of window (HWND 0x" << hwnd << ")";
throw std::system_error( static_cast<int>( err ), std::system_category(), msg.str() );
}
}
Usage:
When using the wrapper function MyShowWindow() you must make sure to catch the exceptions thrown by it. The following example shows how to do that.
int main(){
try{
// Passing an invalid handle to MyShowWindow() will throw
// std::system_error exception. There may be other reasons for the
// function to fail, for instance if you pass the window handle of
// another process to which you don't have access as an argument
// to the function.
HWND anInvalidHandle = 0;
MyShowWindow( anInvalidHandle, true );
}
catch( std::system_error& e ){
// Catch the exception thrown by MyShowWindow() and report all
// available error details.
// e.code() outputs the error code retrieved via GetLastError().
std::cout << "Error: " << e.what() << std::endl
<< "Error code: " << e.code() << std::endl;
}
return 0;
}
Output:
Error: Could not change visibility of window (HWND 0x00000000): UngĀ³ltiges Fensterhandle
Error code: system:1400
The message says "invalid window handle", the error code corresponds to ERROR_INVALID_WINDOW_HANDLE.
Note:
Although the provided MyShowWindow() function only supports SW_HIDE and SW_SHOW functionality of ShowWindow, the remaining functionality could propably be provided by using additional SetWindowPos flags (e. g. SW_SHOWNA maps to SWP_SHOWWINDOW | SWP_NOACTIVATE) or calling other Windows API functions that provide this functionality and are documented to support GetLastError().
ShowWindowAsync while asynchronous in nature, it does however tell you if the operation was started successfully or not. Depending on what you are doing, it might be a usable alternative.
ShowWindow does not have any error-awareness. If the window provided does not exist (or is not accessible), it just returns false.
ShowWindow in fact does not do much more than sending a WM_SHOW message to the targeted window. Because of the nature of the windows message queue, ShowWindow has no knowledge about its completion status. Although, as pointed out in the comments, WM_SHOW is handled synchronously, the message queue itself has no built-in error reporting mechanism aside from sending error messages back to the sender.
[edit]
It seems that GetLastError reports an invalid window handle when trying to access a non-existing window. To me, this is an unknown behaviour as normally a return value should indicate whether to use GetLastError or not. However, this can be easily avoided by testing for the window manually in advance (see: IsWindow)
i have problem with this code:
int
WINAPI
Getdesc(IN WORD wcode,
OUT LPWSTR lpBuf)
{
WCHAR szDescription[256];
int res = LoadStringW(NULL,wcode,szDescription,256);
if(res == 0)
{
wcscpy(lpBuf, L"Undefined");
return 0;
}
else
{
wcscpy(lpBuf,szDescription);
return 0;
}
}
The function is placed in a DLL, and when i access it, it always returns "Undefined",
I think there is problem in my LoadString call, but i can't figure it out.
I'm new to windows programming, any help would be appreciated
The problem is that you are passing NULL as the HINSTANCE parameter. That means that you look for the resource in the executable host and not the DLL. You'll have to pass the module handle of the DLL. You are provided with that instance handle as the first parameter passed to your DllMain function.
If you are compiling with MSVC then you could use __ImageBase to obtain the module handle. Personally I would suggest that making a note of the value passed to DllMain is a cleaner approach. It avoids taking a dependency on one specific compiler.
Note also that you can call GetLastError in case LoadString fails to obtain more information about the reason for the error. It's quite possible that would have helped you identify the fault.
GetCommState fails with error code 87.
Can this system call be used with any type of serial port? I have an RS422 USART card. Port can be configured as Sync or Async. I have it configured as Async and was using boost:asio. I noticed the failure while stepping through the code and ended up in the code below in a boost file. I took it out and put it in my main along with a call to CreateFile right before it. I get a good handle(handle is not INVALID_HANDLE_VALUE). I can't get it to return successful. Any ideas? I called the serial card tech support and I was told this call should work.
Here is my code:
using namespace std; // For memset.
DCB dcb;
//memset(&dcb, 0, sizeof(DCB));
SecureZeroMemory(&dcb, sizeof(DCB)); // tried this from a suggestion I saw online somewhere
dcb.DCBlength = sizeof(DCB);
if (!GetCommState(hDevice, &dcb))
{
DWORD last_error = ::GetLastError();
CloseHandle(hDevice);
exit(1);
// ec = boost::system::error_code(last_error,
// boost::asio::error::get_system_category());
//return ec;
}
If you were on a *NIX platform, check out /usr/include/errno.h (which probably has a #include for /usr/include/sys/errno.h) and see what matches up with your return code. Since you're on Windows, you'll have to hit up MSDN. Error code 87:
ERROR_INVALID_PARAMETER 87 One of the parameters was invalid.
I'd guess GetCommState() isn't liking your hDevice parameter. The call to SecureZeroMemory() shouldn't be necessary if you use memset(). Have you checked to see if all of the necessary parameters of dcb are set with respect to hDevice?