Welcome

Wheresoever you go, go with all your heart. (Confucius)
Showing posts with label MFC. Show all posts
Showing posts with label MFC. Show all posts

5/25/2012

Using Key simulation in MFC

Sometimes, we need to send keys to another process when developing MFC application.
We called sending keys "Key simulation"
For this purpose, we can use the function "SendInput" as a function of MFC.
Here I will describe an example. So, see the function description.


We have to get a window handle to send keys.
In MFC, there are several methods for this. Here I will use FindWindowEx method.
When finding the specific window handle, you can describe "class name" or "Window title name"
I think "Window title name" is more convenient.

// Get window handle

HWND hWindow = ::FindWindowEx(NULL, NULL, "Class Name", 0);
or
HWND hWindow = ::FindWindowEx(NULL, NULL, 0, "Window title name");

// Get thread and process id

PROCESS_INFORMATION pi;
pi.dwThreadId = ::GetWindowThreadProcessId(hWindow, &(pi.dwThreadId));

SendKey(WORD('A'), MapVirtualKey('A',0), pi);


Refer two methods 'SendKey' and 'SendCtrlShiftKey'


void SendKey(WORD vk, WORD scan, PROCESS_INFORMATION pi)
{

INPUT is;

is.type = INPUT_KEYBOARD;  //INPUT_KEYBOARD = 1
is.ki.time = 0;

is.ki.wVk = vk;
is.ki.wScan = scan;
is.ki.dwFlags = NULL;
is.ki.dwExtraInfo = NULL;

SendInput(1, &is, sizeof(INPUT)); // Key down
WaitForInputIdle( pi.hProcess, INFINITE );

is.ki.wVk = vk;
is.ki.dwFlags = KEYEVENTF_KEYUP;
is.ki.wScan = scan;
is.type = INPUT_KEYBOARD;

SendInput(1, &is, sizeof(INPUT)); // Key up
WaitForInputIdle( pi.hProcess, INFINITE );
}


void SendCtrlShiftKey(WORD vk, PROCESS_INFORMATION pi)
{
INPUT inp[6];
short Ecnt = 0x00;


// VK_CONTROL down.
inp[0].ki.time = NULL;
inp[0].type = INPUT_KEYBOARD;
inp[0].ki.dwExtraInfo = NULL;
inp[0].ki.dwFlags = NULL;
inp[0].ki.wVk = VK_CONTROL;
inp[0].ki.wScan = MapVirtualKey(VK_CONTROL,0);

// VK_SHIFT down.
inp[1].ki.time = NULL;
inp[1].type = INPUT_KEYBOARD;
inp[1].ki.dwExtraInfo = NULL;
inp[1].ki.dwFlags = NULL;
inp[1].ki.wVk = VK_SHIFT;
inp[1].ki.wScan = MapVirtualKey(VK_SHIFT,0);

// Character Key down.
inp[2].ki.time = NULL;
inp[2].type = INPUT_KEYBOARD;
inp[2].ki.dwExtraInfo = NULL;
inp[2].ki.dwFlags = NULL;
inp[2].ki.wVk = vk;
inp[2].ki.wScan = MapVirtualKey(vk,0);

// VK_CONTROL up.
inp[3].ki.time = NULL;
inp[3].type = INPUT_KEYBOARD;
inp[3].ki.dwExtraInfo = NULL;
inp[3].ki.dwFlags = KEYEVENTF_KEYUP;
inp[3].ki.wVk = VK_CONTROL;
inp[3].ki.wScan = MapVirtualKey(VK_CONTROL,0);

// VK_SHIFT up.
inp[4].ki.time = NULL;
inp[4].type = INPUT_KEYBOARD;
inp[4].ki.dwExtraInfo = NULL;
inp[4].ki.dwFlags = KEYEVENTF_KEYUP;
inp[4].ki.wVk = VK_SHIFT;
inp[4].ki.wScan = MapVirtualKey(VK_SHIFT,0);

// Character Key up.
inp[5].ki.time = NULL;
inp[5].type = INPUT_KEYBOARD;
inp[5].ki.dwExtraInfo = NULL;
inp[5].ki.dwFlags = KEYEVENTF_KEYUP;
inp[5].ki.wVk = vk;
inp[5].ki.wScan = MapVirtualKey(vk,0);



SendInput(1,inp,sizeof(INPUT)); // VK_CONTROL down
WaitForInputIdle( pi.hProcess, INFINITE );

SendInput(1,&inp[1],sizeof(INPUT)); // VK_SHIFT down
WaitForInputIdle( pi.hProcess, INFINITE );

SendInput(1,&inp[2],sizeof(INPUT)); // Key down
WaitForInputIdle( pi.hProcess, INFINITE );

SendInput(1,&inp[5],sizeof(INPUT)); // Key up
WaitForInputIdle( pi.hProcess, INFINITE );

SendInput(1,&inp[4],sizeof(INPUT)); // VK_SHIFT up
WaitForInputIdle( pi.hProcess, INFINITE );

SendInput(1,&inp[3],sizeof(INPUT)); // VK_SHIFT up
WaitForInputIdle( pi.hProcess, INFINITE );
}

10/11/2011

Single instance in MFC

Sometimes you want to make your application only with a single instance.
Unfortunately MFC don't provide any APIs. However, there is the simplest method by MUTEX.

First, you create the globally unique identifier (GUID) to create MUTEX.
MFC provides creating GUID: Tools-Create GUID.
after creating it, just copy and paste in your code.

The following code located in InitInstance() of MFC.

CString stringGUID = L"........";
HANDLE hMutex = CreateMutex(NULL, TRUE, stringGUID);
if( GetLastError() == ERROR_ALREADY_EXISTS )
{
    CloseHandle(hMutex);
    return FALSE;
}

11/16/2010

[MFC] using Formview Dialog

In many case of the form design,
you need to attach the designed form to other forms.
To achieve this purpose, we can use the formview dialog.
The formview dialog is not special.
Of options of the general dialog, you set up such as Boder = false and Style = Child.

For example, consider that IDD_FORMVIEW and IDD_FORMVIEW2 is designed.

And you want to attach these to other form views or dialogs.
The source code is the following

// CTestLocalPanel *panel;   -- class CTestLocalPanel : public CDialog for IDD_FORMVIEW
// CTestLocalPanel *panel2;   -- class CTestLocalPanel2 : public CDialog for IDD_FORMVIEW2

void CTestMFCView::OnBnClickedButton1()
{
    if( panel2 )
    {
        panel2->ShowWindow(SW_HIDE);
        panel2->DestroyWindow();
        delete panel2;
        panel2 = 0;
    }
    if( !panel )
    {
        CRect rect;
        panel = new CTestLocalPanel();
        panel->Create(IDD_FORMVIEW, this);
        panel->GetWindowRect(&rect);
        panel->MoveWindow(5, 150, rect.Width(), rect.Height()); // Moving Dialog forms into the specific position
        panel->ShowWindow(SW_SHOW);
    }

    UpdateData(false);
}
void CTestMFCView::OnBnClickedButton2()
{
    if( panel )
    {
        panel->ShowWindow(SW_HIDE);
        panel->DestroyWindow();
        delete panel;
        panel = 0;
    }
    if( !panel2 )
    {
        CRect rect;
        panel2 = new TestLocalPanel2();
        panel2->Create(IDD_FORMVIEW1, this);
        panel2->GetWindowRect(&rect);
         ->MoveWindow(5, 150, rect.Width(), rect.Height());
        panel2->ShowWindow(SW_SHOW);
    }

    UpdateData(false);
}

[MFC] Show/Hide Menubar

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
      if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
            return -1;
   
      if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
            | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
            !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
      {
            TRACE0("Failed to create toolbar\n");
            return -1;      // fail to create
      }

      if (!m_wndStatusBar.Create(this) ||
            !m_wndStatusBar.SetIndicators(indicators,
              sizeof(indicators)/sizeof(UINT)))
      {
            TRACE0("Failed to create status bar\n");
            return -1;      // fail to create
      }

      // TODO: Delete these three lines if you don't want the toolbar to
      //  be dockable
      m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
      EnableDocking(CBRS_ALIGN_ANY);
      DockControlBar(&m_wndToolBar);

      // OrgMenu is defined in the member variable of CMainFrame
      // Load menu on create
      OrgMenu.LoadMenu(IDR_MAINFRAME);
      return 0;
}

void CMainFrame::OnHide()
{
      // hide menu
      SetMenu(NULL);
}

void CMainFrame::OnShow()
{
      // show menu
      SetMenu(&OrgMenu);
}