Posts

Showing posts with the label win32api

the one and only, the TB_ADDSTRING message !

If you try to use TB_ADDSTRING with the string from the resource then you might had blown your head trying to figure out what the heck is happening, why does it fail: const int iIndex = ::SendMessage( hToolBar, TB_ADDSTRING, hResource, IDS_TBSEARCH); // string id from module's resource iIndex is returned -1 (indicating an error). Now, I looked at my MSDN from disk and then looked at the online version. Nada. But the old friend Mr. Google saved the day (he always does). I got this page: The problem with TB_ADDSTRING or the AddString method that is simply a wrapper to this message is that the first character in the string resource is used as separator and is replaced with a NULL character. So your string resource must be something similar to: "|Button text||" where the pipe character is replaced with '\0'. This is because the string you pass with TB_ADDSTRING message must have a double null terminator. You can also use the TB_ADDSTRINGS messa...

MAKEINTRESOURCE macro

Many Win32 API functions use a LPCTSTR parameter as resource name or type. For example, a trivial one: HICON LoadIcon(HINSTANCE hInstance, LPCTSTR lpIconName); And the documentation for the lpIconName states that: Pointer to a null-terminated string that contains the name of the icon resource to be loaded. Alternatively, this parameter can contain the resource identifier in the low-order word and zero in the high-order word. Use the MAKEINTRESOURCE macro to create this value. Now, how the LoadIcon code knows to diferentiate between a resource string name and a predefined constant like IDI_ASTERISK which is defined as: #define IDI_ASTERISK MAKEINTRESOURCE(32516) We are used to the wizard generated resource IDs in our applications but a resource can have any null terminated string as name and type too. Look to the FindResource function for example. All resource Win32API functions use the macro IS_INTRESOURCE(id) BOOL IS_INTRESOURCE( WORD wInteger ); #define I...

Win32 HANDLEs

Each time when you use a win32 API which uses a HANDLE remember that the handle Must be valid (not closed). It is important to understand the concepts of the handle being signaled and being closed. Signaled state refers to the handle state. It can be signaled or unsignaled. Wait functions for example, like WaitForSingleObject, block current thread until the object gets signaled. A handle is said to be closed when its reference count reaches zero value. When this happens the handle is closed and doing any waiting on it is error prone. A handle is a pointer on an object. Wait functions check the state of the object, hence it is a must that the handler (the pointer) is valid. Otherwise, waiting functions wont work properly (while waiting on an invalid handle, you might wait indefinetly). One example of bogus use is with MFC AfxBeginThread function. Its default behaviour is to auto 'delete' the thread, i.e to close its handle. Its bad to use the returned handle after the thread is ...

CreateDialog, CreateWindow or any other window\dialog creation function fails and GetLastError is 0

... then check if you have called InitCommonControls() at very start of your application if you use any common controls (list view, tree view ,etc)

process termination

Ive just looked to an interesting blog article talking about when a process terminates. http://blog.kalmbachnet.de/?postid=65 It seem that there is a subtle difference between how a console application (the main() CRT function) and a Win32 application (WinMain) is handling the process termination. if you have this: DWORD WINAPI MyThread2(LPVOID) { while(true) { } return 0; } #pragma comment(linker, "/entry:myMain") int WINAPI myMain() { DWORD dwThreadId; CloseHandle(CreateThread(NULL, 0, MyThread2, NULL, 0, &dwThreadId)); return 0; } the application is a windows application (using myMain entrypoint) and it run infinitely. but a similar console application: int t_main() { DWORD dwThreadId; CloseHandle(CreateThread(NULL, 0, MyThread2, NULL, 0, &dwThreadId)); return 0; } will return immediately after the 'return 0;' the difference is this one: the console application uses CRT which, after the user code return from main, it calls ExitProcess which terminates the a...

SuspendThread

as the msdn says SuspendThread is for debugging purposes and should not be used. it may be tempting to use it to pause a worker thread for example but it might not be ok. the worker thread can be in the middle of executing a CRT function which is thread safe, using sychronization. if the worker thread is paused after the lock is done, trying to execute from another thread a CRT function, which uses the same syncronization access, might get to a deadlock.

stuff to do on DLL_PROCESS_ATTACH

it is guaranteed you can call any Kernel32.dll function on the DLL_PROCESS_ATTACH. Calling any other function from other library is not ok, as the DLLs may not be loaded at that time (although your code links with those libs). more info can be found in the J. Richter book. and J.Robbins say some problem he had in the past with some thread work in DLL_PROCESS_ATTACH.

using std lib functions between dlls

it is OK to have functions with variables of class vector or other std lib class, and call these functions between different DLLs executable modules or between EXE and DLLs, as long as both of the modules are linked in the same way to the C run time library (hence memory is alocated by the same code) . info i think can be found in "C/C++ Run-Time Library Considerations", Chapter 6 in "Programming Apps for Windows" by J. Richter.

oversee CloseHandle

there are many WinAPI functions which create and return a HANDLE object, like CreateThread, CreateFile. in windows header file, a HANDLE is defined like this typedef void* HANDLE doing a 'CloseHandle' more than it is needed on the same HANDLE value is as bad as doing 'delete' on the same pointer. the docs say: "CloseHandle invalidates the specified object handle, decrements the object's handle count, and performs object retention checks. After the last handle to an object is closed, the object is removed from the system." so as long as the handle count is not zero, its logic of course to call CloseHandle. there are few considerations with the HANDLE objects: - some functions are not requiring to do CloseHandle on the their returned HANDLE object; so always, always read the docs; dont rely on the fact you are an experienced WinAPI programmer; the behaviour might be (it is !) different between functions (in fact you can find an example in the John Robbins bo...

multithreading issue

ok, here is my task: i have a dialog (main thread) and i have a worker thread running which updates a progressbar on the GUI. when i press the close button i want the main thread and the worker thread to end cleanly (i want tthe threads to be closed nicely, without any TerminateThread or anything) now, the problem stay in the fact that when i signal (using an event or something) the worker thread to end and then wait for it to end (using WaitForSingleObject for example) it is possible that in this time the worker thread to send a message to the GUI to update the progressbar(using SendMessage). Now, some may say why that SendMessage is a mistake but maybe not. I want to be sure that the GUI and worker are synchronized perfectly (i dont want to use PostMessage; in some situations, for example when a buffer is needed to be sent, PostMessage only will not work (the buffer needs to be available when the message arrive to the receiver queue), hence, for PostMessage, some queue mechanism migh...

shell api power

i've discovered some months ago that the shell libary shlwapi.dll has, beside some well known functions like SHBrowseForFolder also some tiny functions but very useful. instead of writing your own functions why dont use those which already exist, especially if come from OS DLL's ? u are sure they are working OK and also it may be faster then yours (applicatinos like Windows Explorer use the DLL already, hence the functions might already be loaded in the memory pages) those functions stay mostly in so called "Shell Lightweight Utility Functions", and they are grouped in String Functions, Path Functions Registry Functions Color Palette Functions, Miscellaneous For example, i needed a function which gives a text formatted to display the size of a file like this: 100 MB 123 KB ... this function already exists in shell lib, StrFormatByteSizeW Function or StrFormatByteSizeA Function so I will always check out the shell functions whenever i have this kind of small tasks to d...