Tuesday, March 22, 2016

ON_NOTIFY vs. OnNotify

It is not always easy to catch WM_NOTIFY send from control to its parent window. 

In this case they want to notify parent CFileView from control CViewTree with WM_NOTIFY TVN_SELCHANGED message. And here message map just doesn't work:

ON_NOTIFY(TVN_SELCHANGED, 4, OnItemsSelChanged)

They should do it in virtual OnNotify function, not using message map. If OnNotify doesn't met correct handler, message would go to parent CMainFrame, and there you can use message map.

BOOL CFileView::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
   if (nmHdr->idFrom != 4)
      return CDockablePane::OnNotify(wParam, lParam, pResult);
   if (nmHdr->code == TVN_SELCHANGED)
   {
      OnItemsSelChanged((NMHDR*)lParam, pResult);
      return TRUE;
   }
   return FALSE;
}

Thursday, November 12, 2015

Decryption of DLGINIT .rc file entry

Visual Studio saves ComboBox item list in DLGINIT entries of .rc files as ASCIIZ strings, in WORD format:

IDD_DIALOG1 DLGINIT
BEGIN
    IDC_STR1, 0x403, 16, 0
0x7241, 0x2063, 0x6c63, 0x636f, 0x776b, 0x7369, 0x0065,

    IDC_STR2, 0x403, 18, 0
0x6c41, 0x6177, 0x7379, 0x6120, 0x2074, 0x6874, 0x2065, 0x6964, 0x0065,
    0
END

Using simple type conversion we can reveal, what do these strings contain.

Thursday, September 17, 2015

Understanding Mutex entity

Studying example from MSDN article Using Mutex Objects some questions arise about mutex entity.
Here are experimentally proved suggestions:
  1. Mutexes are like files, open and create them with CreateMutex, close with CloseHandle (for files you use CreateFile, CloseHandle)
  2. Unnamed mutex is like critical section
  3. Mutexes are deleted after CloseHandle when no application currently have them opened
You can understand these things from running 10 simple programs which in short do the following:
HANDLE h
main(){
  h = CreateMutex("Global\\SuperMutex")
  CreateThread(WriteToDatabase)
  CloseHandle(h)
}

WriteToDatabase()
{
  WaitForSingleObject(h)
  ReleaseMutex(h)
}
Some programs create h = 0x3c, some h = 0x44
Some create mutex via CreateMutex while having ERROR_ALREADY_EXISTS

Pic 1. Running 10 of these programs:


Example sources are here...

Monday, August 31, 2015

Test f() for multithreading

Here is a copy-paste template to test your code for multithreading. Let's say you want to test your function
int f() { ... }
for multithreading. Use this code to test f() running from number of threads simultaneously:

struct TESTPARAM
{
   int threadNo;
   LONG* m_pnCount;
};

DWORD WINAPI _msgTestThread(void* pParam)
{
   TESTPARAM* par = (TESTPARAM*)pParam;
   char buf[1014];

   int tmax = 1000;
   int tstep = 100;
   for (int t = 0; t<tmax; t+=tstep)
   {
      f();
      Sleep(tstep);
   }

   InterlockedDecrement(par->m_pnCount);
   delete par;
   return 0;
};

int Start()
{
   LONG nThreadCount = 0;
   int THREAD_MAX = 10;

   //msg::Message threads
   for (int i = 0; i<THREAD_MAX; i++)
   {
      //new, otherwise TESTPARAM will not reach thread in _msgTestThread,
      //and will be deleted on closing scope }
      TESTPARAM * par = new TESTPARAM;
      par->threadNo = i;
      par->m_pnCount = &nThreadCount;
      InterlockedIncrement(par->m_pnCount);
     
      DWORD dwThreadID = 0;
      CreateThread(0, 0, _msgTestThread, par, 0, &dwThreadID);
   }

   //Call window procedure until threads are finished
   while (nThreadCount > 0)
   {
      MSG msg;
      if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
      {
         TranslateMessage(&msg);
         DispatchMessage(&msg);
      }
      Sleep(10);
   }
}

Thursday, October 23, 2014

Filtering log files on Windows 7

Note: this is just a reminder about Windows analogues of grep - find and findstr.

Being inspired by this article: http://habrahabr.ru/post/71568/
now leaving some how-to's when working with large log files, containing messages from many processes.

How to get all messages from a process with PID=8238

C:\logs> type file.log | find "8238"
2014-09-19 16:40:22 8238   [INFO] Closing Session
2014-09-20 16:40:22 8238   [INFO] Closing Session
2014-09-22 16:40:35 8238   [WARNING] Error: No IC output on selected net (i.e., no driver).Stopping.
2014-09-22 16:40:50 8238   [INFO] Close Session: Design file: demo2.p

2014-09-22 16:41:38 8238   [INFO] Close Session: Design file: demo2.p
2014-09-26 15:45:11 8238   [INFO] Close Session: Design file: demodiff.p


How to get messages from interval [2014-09-22, 2014-09-26]

C:\logs> type file.log  | findstr /r /C:"2014-09-2[2-6]"
2014-09-22 16:40:22    [INFO] Closing Session: 
2014-09-22 16:40:35    [WARNING] Error: No IC output on selected net (i.e., no driver).Stopping.
2014-09-22 16:40:50    [INFO] Close Session: Design file: demo2.p

2014-09-22 16:41:38    [INFO] Close Session: Design file: demo2.p
2014-09-26 15:45:11    [INFO] Close Session: Design file: demodiff.p


Note that  /r stands for regular expressions. But regexps are limited in findstr, only [class] or [a-b] is allowed. See http://technet.microsoft.com/ru-ru/library/bb490907.aspx for reference.

Thursday, October 2, 2014

Compiling .cpp files in FAR by pressing Enter

Sometimes we write small prototype console applications to test any functions or learn C++ features. It would be nice just to edit .cpp file and get .exe compiled at once, like Linux guys can do just by entering gcc command.



What you have to do - just to mimic
Start->All-Programs->Microsoft Visual Studio 2008->Visual Studio Tools->Visual Studio 2008 Command Prompt, which simply calls
%comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat"" x86

Thursday, September 25, 2014

Odd HINSTANCE

Being called from DLL module, guess, which one would give you odd result?

HINSTANCE h1 = AfxGetInstanceHandle();
HINSTANCE  h2 = GetModuleHandle(NULL);
HINSTANCE h3 = AfxGetApp()->m_hInstance;
HINSTANCE h4 = theApp.m_hInstance;