All posts by Chun Kang

투명 윈도우 만들기

You should be able to use this demo as a skeleton application for your own project.

A standard CDialog MFC EXE application was created with the wizard and apart from the standard supplied code, the following functions were overridden.

void OnClose() Used to clean up some resources on exit.
void OnPaint() Used to paint the bimap into the region.
void OnSize(UINT nType, int cx, int cy) Used to create the region and position and resize the dialog.
void OnLButtonDown(UINT nFlags, CPoint point) To allow the dialog to be dragged by clicking anywhere.

A button was created to allow the user to close the dialog. A timer was created to demonstrate auto closing after a period of time.

The image is a normal bmp file that is loaded by the app and used to paint the dialog. TRANSPARENTCOLOR is defined in the dialog class header as bright purple (RGB(255, 0, 255), but this could be changed to any colour you like.

The dialog window is auto sized to the size of the loaded bitmap then a region created based on the transparent colour. The dialog is then positioned in the centre of the current screen. This was done as an example for those who want to use this application as a splash windows.



#define TRANSPARENTCOLOR RGB(255, 0, 255);

BITMAP  m_Bitmap;                // Struct to hold info about the bitmap
HBITMAP m_hBitmap;                // Handle of the bitmap

void CTransparentDialogDlg::OnClose()
{
        // TODO: Add your message handler code here and/or call default
        DeleteObject(m_hBitmap);        //not really need but what the heck.
        CDialog::OnClose();
}

void CTransparentDialogDlg::OnPaint()
{
        // device context for painting
        CPaintDC dc(this);
        //Create a memory DC
        HDC hMemDC = ::CreateCompatibleDC(NULL);
        //Select the bitmap in the memory dc.
        SelectObject(hMemDC, m_hBitmap);
        //Copy the memory dc into the screen dc
        ::BitBlt(dc.m_hDC, 0, 0, m_Bitmap.bmWidth, m_Bitmap.bmHeight, hMemDC, 0, 0, SRCCOPY);
        //Delete the memory DC and the bitmap
        ::DeleteDC(hMemDC);
        CDialog::OnPaint();
}

void CTransparentDialogDlg::OnSize(UINT nType, int cx, int cy)
{
        CDialog::OnSize(nType, cx, cy);
        // Load the image
        m_hBitmap = (HBITMAP)LoadImage(GetModuleHandle(NULL), “Image.bmp”, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
        if (m_hBitmap == NULL)
        {
                MessageBox(“Error loading bitmap”);
                return;
        }
        //Get information about the bitmap..
        GetObject(m_hBitmap, sizeof(m_Bitmap), &m_Bitmap);        // Get info about the bitmap
        // Put the bitmap into a memory device context
        CPaintDC dc(this);
        //get a memory dc object
        CDC dcMem;
        //create a compatible dc
        dcMem.CreateCompatibleDC(&dc);        // Select the bitmap into the in-memory DC
        //Select the bitmap into the dc
        CBitmap* pOldBitmap = dcMem.SelectObject(CBitmap::FromHandle(m_hBitmap));
        //Create a couple of region objects.
        CRgn crRgn, crRgnTmp;
        //create an empty region
        crRgn.CreateRectRgn(0, 0, 0, 0);
        //Create a region from a bitmap with transparency colour of Purple
        COLORREF crTransparent = TRANSPARENTCOLOR;        
        int iX = 0;
        for (int iY = 0; iY < m_Bitmap.bmHeight; iY++)
        {
                do
                {
                        //skip over transparent pixels at start of lines.
                        while (iX <= m_Bitmap.bmWidth && dcMem.GetPixel(iX, iY) == crTransparent)
                                iX++;
                        //remember this pixel
                        int iLeftX = iX;
                        //now find first non transparent pixel
                        while (iX <= m_Bitmap.bmWidth && dcMem.GetPixel(iX, iY) != crTransparent)
                                ++iX;
                        //create a temp region on this info
                        crRgnTmp.CreateRectRgn(iLeftX, iY, iX, iY+1);
                        //combine into main region.
                        crRgn.CombineRgn(&crRgn, &crRgnTmp, RGN_OR);
                        //delete the temp region for next pass (otherwise you’ll get an ASSERT)
                        crRgnTmp.DeleteObject();
                }while(iX < m_Bitmap.bmWidth);
                iX = 0;
        }
        //Centre it on current desktop
        SetWindowRgn(crRgn, TRUE);
        iX = (GetSystemMetrics(SM_CXSCREEN)) / 2 – (m_Bitmap.bmWidth / 2);
        iY = (GetSystemMetrics(SM_CYSCREEN)) / 2 – (m_Bitmap.bmHeight / 2);
        SetWindowPos(&wndTopMost, iX, iY, m_Bitmap.bmWidth, m_Bitmap.bmHeight, NULL);

        // Free resources.
        dcMem.SelectObject(pOldBitmap);        // Put the original bitmap back (prevents memory leaks)
        dcMem.DeleteDC();
        crRgn.DeleteObject();
}

void CTransparentDialogDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
        // TODO: Add your message handler code here and/or call default
        PostMessage( WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM( point.x, point.y));
        CDialog::OnLButtonDown(nFlags, point);
}

불투명 윈도우 만들기

 

* 불투명 윈도우 만들기

방금전에 책에서 본 예제로 만든겁니다.

님의 코드보다 더 자원을 먹을지는 모르겠지만 참고하세요.

윈도 2000이상에서만 된다고 하네요.

전역입니다 :

// 투명 설정을 위한 상수 정의
#define WS_EX_LAYERED       0x00080000
#define LWA_ALPHA           0x00000002

OnInitDialog에 추가 :

    // 확장 스타일에 WS_EX_LAYERED를 추가한다
    ModifyStyleEx(0, WS_EX_LAYERED);

    // user32.dll에 있는 SetLayeredWindowAttributes()의 포인터를 얻는다
    HMODULE hUserDll = ::LoadLibrary(_T(“USER32.dll”));
    typedef BOOL (WINAPI* LPSETTRANSPARENT)(HWND hWnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags);

    LPSETTRANSPARENT lpSetTransparent = NULL;
    lpSetTransparent  = (LPSETTRANSPARENT)::GetProcAddress(hUserDll, “SetLayeredWindowAttributes”);

    if(lpSetTransparent)
        // SetLayeredWindowAttributes() 함수를 호출한다.
        // 세번째 투명도는 0 ~ 255까지의 값을 설정한다
        lpSetTransparent(m_hWnd, NULL, 200, LWA_ALPHA);

    // user32.dll을 닫는다
    ::FreeLibrary(hUserDll);

마우스로 윈도우 드래그하여 이동시키는 비기

윈도우 드래그해서 움직이고 싶은데 어떻게 하는지 모르시는 분은 다음의 이벤트를 추가해 보시라.
 

void Cgdiplus_demoDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
        // 다음과 같이 PostMessage를 넣어주면 간단히 구현 가능
        PostMessage( WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM( point.x, point.y));

        CDialog::OnLButtonDown(nFlags, point);
}

비트맵을 배경으로 뿌리고 그 위에 컨트롤 올리는 방법

사실은 별루 하는 일 없다.

원래 VC++ 프로그램 짜듯 짜되,
배경이미지를 하나 로딩해서 매번 Paint 해주면 된다.


다음과 같이 클레스 선언부에 m_BG라는 비트맵을 선언


HBITMAP m_BG

초기화 부분에서 비트맵 로드한다음

BOOL CCALLIDDlg::OnInitDialog()
{
        CDialog::OnInitDialog();

        // Set the icon for this dialog.  The framework does this automatically
        //  when the application’s main window is not a dialog
        SetIcon(m_hIcon, TRUE);                        // Set big icon
        SetIcon(m_hIcon, FALSE);                // Set small icon
        
        CenterWindow(GetDesktopWindow());        // center to the hpc screen

        // TODO: Add extra initialization here
  m_BG = (HBITMAP)LoadImage(
    AfxGetApp()->m_hInstance,
    MAKEINTRESOURCE(IDB_BG),
    IMAGE_BITMAP,
    0,
    0,
    0);

        return TRUE;  // return TRUE  unless you set the focus to a control
}

OnPaint에서 다음과 같이 걍 뿌려준다
void CCALLIDDlg::OnPaint()
{
        CPaintDC dc(this); // device context for painting


        // TODO: Add your message handler code here
        RECT rc;
  GetClientRect( &rc);

  HDC hdcMem = CreateCompatibleDC(NULL);
  HBITMAP h = (HBITMAP)SelectObject(hdcMem, m_BG);
  
  BitBlt(
    dc.GetSafeHdc(),
    0,
    0,
    rc.right-rc.left,
    rc.bottom-rc.top,
    
    hdcMem,
    0,
    0,
    SRCCOPY
    );
  
  SelectObject( hdcMem, h);
    
  // Do not call CDialog::OnPaint() for painting messages
}

WinCE에서 Key Hooking하는 방법

MSDN에서 알아낸 PDA폰에서의 키 후킹하는 방법입니다.


=======================================================================================

삼성 SPH-M4300에서 프로그래밍 해보고 테스트도 완료했습니다.
잘되더군요.

더 자세한 정보를 알아보시려면 다음의 뉴스그룹을 참조하시고:

http://groups.google.com/group/microsoft.public.windowsce.app.development/browse_thread/thread/e0243550d63d8f63/2bba7323170c798a?lnk=st&q=pocket+pc+SetWindowsHookExW&rnum=5#2bba7323170c798a

샘플 코드 보여드립니다:


extern “C”
{
typedef LRESULT (CALLBACK* HOOKPROC)(int code, WPARAM wParam, LPARAM lParam);


typedef struct tagKBDLLHOOKSTRUCT
{
  DWORD vkCode;  // virtual key code
  DWORD scanCode;  // scan code
  DWORD flags;  // flags
  DWORD time;   // time stamp for this message
  DWORD dwExtraInfo; // extra info from the driver or keybd_event
} KBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT;


HHOOK WINAPI SetWindowsHookExW( int idHook, HOOKPROC lpfn, HINSTANCE hmod, DWORD dwThreadId );
BOOL WINAPI UnhookWindowsHookEx( HHOOK hhk );
LRESULT WINAPI CallNextHookEx( HHOOK hhk, int nCode, WPARAM wParam, LPARAM lParam );
LRESULT CALLBACK KeyboardProc( int code,  WPARAM wParam, LPARAM lParam );
#define SetWindowsHookEx  SetWindowsHookExW



}


HHOOK hKeyboardHook = 0;

#define HC_ACTION  0
#define PPC_KEY_APP1          0xc1
#define PPC_KEY_APP2          0xc2
#define PPC_KEY_APP3          0xc3
#define PPC_KEY_APP4          0xc4
#define PPC_KEY_APP5          0xc5
#define PPC_KEY_SCHEDULE      0xc1
#define PPC_KEY_ADDRESS       0xc2
#define PPC_KEY_MAGICN        0xc3
#define PPC_KEY_LAUNCHER      0xc4
#define PPC_KEY_RECORD        0xc5

#define PPC_KEY_CALL          0x72
#define PPC_KEY_HANGUP        0x73
#define PPC_KEY_VOLUME_UP     0x74
#define PPC_KEY_VOLUME_DOWN   0x75
#define PPC_KEY_VOLUME_UP2    0x26
#define PPC_KEY_VOLUME_DOWN2  0x28
#define PPC_KEY_CANCEL        0x08

#define WH_JOURNALRECORD 0
#define WH_JOURNALPLAYBACK 1
#define WH_KEYBOARD_LL 20

//Notification Code
LRESULT CALLBACK KeyboardProc( int code,  WPARAM wParam, LPARAM lParam )
{
    PKBDLLHOOKSTRUCT pKeyStruct = (PKBDLLHOOKSTRUCT)lParam;
    LRESULT    lResult = 0;


if ((AfxGetMainWnd()->m_hWnd != NULL) &&
     (code   == HC_ACTION)    &&
  (wParam == WM_KEYDOWN) )
{


  switch(pKeyStruct->vkCode )
  {
    case PPC_KEY_APP1:
    case PPC_KEY_APP2:
    case PPC_KEY_APP3:
    case PPC_KEY_APP4:
    case PPC_KEY_APP5:
    case PPC_KEY_CALL:
    case PPC_KEY_HANGUP:
    case PPC_KEY_CANCEL:
   lResult = 1;
   break;
  }


  if (0 == lResult)
    lResult = CallNextHookEx(hKeyboardHook, code,  wParam, lParam); 

  // Return true if hook was handled, false to pass it on
  return lResult;
}


void MyCEView::OnInitialUpdate()
{
  CView::OnInitialUpdate();

  hKeyboardHook = SetWindowsHookExW(
    WH_KEYBOARD_LL, 
    (HOOKPROC) KeyboardProc, // address of hook procedure
    NULL,  // handle to application instance
    0 );
}


BOOL MyCEView::DestroyWindow()
{
  if (0 != hKeyboardHook)
    UnhookWindowsHookEx(hKeyboardHook);

  return CView::DestroyWindow();
}

비트맵을 파일에서 로딩하는 비기

파일로부터 비트맵을 로딩하는 비기 (Loading Bitmaps from a File)

Type : Tips & Tricks
References :Posted by dougalli

Notes :
Originally posted to the VST-plugins mailing list by Sandor Drieënhuizen

Only works in Windows

Code :
class CBitmapEx : public CBitmap
{
        public:
                CBitmapEx(int) : CBitmap(resourceID) { };

                void loadFromFile(char *filename);
};

void CBitmapEx::loadFromFile(char *filename)
{
        BITMAP bm;

        pMask = 0;
        pHandle = (HBITMAP)LoadImage(NULL, filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);

        if (pHandle)
        {
                if (GetObject(pHandle, sizeof(bm), &bm))
                {
                        width = bm.bmWidth;
                        height = bm.bmHeight;
                }
                else
                {
                        NDebug::WriteStr(“*GetObject() failed for bitmap”);
                        NDebug::WriteLine(filename);
                }
        }
        else
        {
                NDebug::WriteStr(“*LoadImage() failed for bitmap “);
                NDebug::WriteLine(filename);
        }
}

CbitmapEx *bitmap = new CBitmapEx(NULL);
bitmap->loadFromFile(“bitmap.bmp”);

//now you can use the object ‘bitmap’ just like a normal CBitmap object.

프로그램에서 버젼(version) 정보 읽어주는 소스

가끔 MFC나 Delphi로 프로그램 만들다 보면,
내가 만든 프로그램에 포함된 리소스에서 버젼을 읽어오고 싶을때가 있다.

본 소스는 버젼을 읽어다 뿌려주는 샘플코드입니다.

다음의 코드를 상단부에 선언하시고

String GetVersionInfo(HMODULE hLib, CString csEntry)
{
    CString csRet;
   
    if (hLib == NULL)
        hLib = AfxGetResourceHandle();
   
    HRSRC hVersion = FindResource( hLib, MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION );
    if (hVersion != NULL)
    {
        HGLOBAL hGlobal = LoadResource( hLib, hVersion );
        if ( hGlobal != NULL)
        {
           
            LPVOID versionInfo = LockResource(hGlobal);
            if (versionInfo != NULL)
            {
                DWORD vLen,langD;
                BOOL retVal;
               
                LPVOID retbuf=NULL;
#ifdef _UNICODE
                static TCHAR fileEntry[256];
                wsprintf(fileEntry,_T(“VarFileInfoTranslation”));
#else
                static char fileEntry[256];
                sprintf(fileEntry,_T(“VarFileInfoTranslation”));
#endif
               
               
                retVal = VerQueryValue(versionInfo,fileEntry,&retbuf,(UINT *)&vLen);
                if (retVal && vLen==4)
                {
                    memcpy(&langD,retbuf,4);
#ifdef _UNICODE
                    wsprintf(fileEntry, _T(“StringFileInfo\%02X%02X%02X%02X\%s”),
                        (langD & 0xff00)>>8,langD & 0xff,(langD & 0xff000000)>>24,
                        (langD & 0xff0000)>>16, csEntry);
#else
                    sprintf(fileEntry, _T(“StringFileInfo\%02X%02X%02X%02X\%s”),
                        (langD & 0xff00)>>8,langD & 0xff,(langD & 0xff000000)>>24,
                        (langD & 0xff0000)>>16, csEntry);
#endif
                }
                else
#ifdef _UNICODE
                    wsprintf(fileEntry, L”StringFileInfo\%04X04B0\%s”, GetUserDefaultLangID(), csEntry);
#else
                sprintf(fileEntry, “StringFileInfo\%04X04B0\%s”, GetUserDefaultLangID(), (LPCTSTR)csEntry);
#endif
               
                if (VerQueryValue(versionInfo,fileEntry,&retbuf,(UINT *)&vLen))
#ifdef _UNICODE
                    csRet = (TCHAR*)retbuf;
#else
                csRet = (char*)retbuf;
#endif
            }
        }
       
        UnlockResource( hGlobal );
        FreeResource( hGlobal );
    }
   
    return csRet;
}

CString FormatVersion(CString cs)
{
    CString csRet;
    if (!cs.IsEmpty())
    {
        cs.TrimRight();
        int iPos = cs.Find(‘,’);
        if (iPos == -1)
            return “”;
        cs.TrimLeft();
        cs.TrimRight();
        csRet.Format(“%s.”, cs.Left(iPos));
       
        while (1)
        {
            cs = cs.Mid(iPos + 1);
            cs.TrimLeft();
            iPos = cs.Find(‘,’);
            if (iPos == -1)
            {
                csRet +=cs;
                break;
            }
            csRet += cs.Left(iPos);
        }
    }
   
    return csRet;
}

그리고 버젼은 다음과 같이 읽어주시면됩니다.

CString g_Version = FormatVersion(GetVersionInfo(NULL, “FileVersion”));

RDP(Remote Desktop Protocol) Port 값 가져오고/바꿔주기

리모트 데스크탑 포트 번호 바꿔주는 프로그램 소스입니다.

첨부파일은 이를 구현한 어플리케이션입니다.
 

DWORD GetRDPPortNo()
{
 HKEY hKey;
 long dwSize=0;
 DWORD PortNo=3389;
 DWORD dwDisp, dwType;

 if (RegCreateKeyEx(
  HKEY_LOCAL_MACHINE,       
  “SystemCurrentControlSetControlTerminal ServerWinStationsRDP-Tcp”,
  0,
  NULL,
  REG_OPTION_NON_VOLATILE,
  KEY_READ,
  NULL,
  &hKey,
  &dwDisp) == ERROR_SUCCESS)
 {
  dwSize=sizeof(DWORD);
  RegQueryValueEx( hKey, “PortNumber”, NULL, &dwType, (unsigned char *)&PortNo, (unsigned long *)&dwSize);
  
  if (!dwSize) PortNo=3389;

  RegCloseKey(hKey);
 }

 return PortNo;
}

void SetRDPPortNo(DWORD PortNo)
{
 HKEY hKey;
 DWORD dwDisp;

 if (RegCreateKeyEx(
  HKEY_LOCAL_MACHINE,       
  “SystemCurrentControlSetControlTerminal ServerWinStationsRDP-Tcp”,
  0,
  NULL,
  REG_OPTION_NON_VOLATILE,
  KEY_ALL_ACCESS,
  NULL,
  &hKey,
  &dwDisp) == ERROR_SUCCESS)
 {
  RegSetValueEx( hKey,
   “PortNumber”,
   0,
   REG_DWORD,
   (const unsigned char *)&PortNo,
   sizeof(DWORD));
  
  
  RegCloseKey(hKey);
 }

 if (RegCreateKeyEx(
  HKEY_LOCAL_MACHINE,       
  “SystemCurrentControlSetControlTerminal ServerWinStationsconnection”,
  0,
  NULL,
  REG_OPTION_NON_VOLATILE,
  KEY_ALL_ACCESS,
  NULL,
  &hKey,
  &dwDisp) == ERROR_SUCCESS)
 {
  RegSetValueEx( hKey,
   “PortNumber”,
   0,
   REG_DWORD,
   (const unsigned char *)&PortNo,
   sizeof(DWORD));
  
  
  RegCloseKey(hKey);
 }
}

Tokunaga Hideaki – Ichiban

여성틱한 보이스를 소유하고 있으면서
노래에 호소력을 실어주는 가수.

처음에 냄비라는 내 친구가 소개시켜줘서 들었는데,
그때의 그 감동이 지금까지 밀려온다.

며칠전 미국정부에 의해 문 닫은 당나귀를 통해서 음악은 몇개 다운 받아서 들었는데,
이 뮤직비디오는 토쿠나가 히데아끼의 대표적인 곡 중 하나다.

소년대 – 데카메론 이야기

일본 유명 프로중 PLAYZONE이라는 프로가 있다.

슬램덩크의 채치수를 연상케 하는 키큰 아저씨가 바로 사회자인데,
입담이 좋아 프로그램을 오랫동안 진행했다고 한다.

우리나라로 치면 젊음의 행진 내지는 가요톱텐 비스무리한거라고나 할까?

여기서 소년대가 부른 노래…

오래된 영상이라 좀 어설픈면도 있지만,
당시 일본 소녀들의 가슴을 뭉클하게 만들었던 꽃미남 3인방 소년대의 현란한 무대~