2011年12月14日 星期三

Libcurl

build DLL Release

copy curl\lib\DLL-Release\
libcurl_imp.lib
libcurl.dll

[Usage]
At project properties:
Linker:
General: Additional Library directories :.\curl\lib\x64
Input: Additional Dependencies: libcurl_imp.lib

then put libcurl.dll into exe folder.

2011年11月21日 星期一

LCID, LanguageID

LCID lcid  = GetSystemDefaultLCID();
WORD LangID = LANGIDFROMLCID(lcid);
WORD PrimID = PRIMARYLANGID(LangID);
WORD SubID = SUBLANGID(LangID);

2011年11月17日 星期四

Stop CURL_EASY_PERFORM

Any of the callbacks (read/write/header/progress/debug/...) can be used to abort the transfer.


int Curlplus::writer(char *data, size_t size, size_t nmemb, void *lParam)
{
    if (lParam == NULL)
        return 0;

     Curlplus* pThis = (Curlplus* )lParam;
       int len = size*nmemb;

if(!pThis->m_bStopParse)
pThis->vParseData(data,len);
        else
return CURLE_ABORTED_BY_CALLBACK;
}

2011年9月6日 星期二

WaitForMultipleObjects

 CClassView* pThis = (CClassView*) param;
pThis->m_bReadDone = false;
pThis->m_wndNodeCtrl.m_vctFileInfo.clear();
pThis->m_wndNodeCtrl.m_strEventInfo.clear();

HANDLE handles[2];
CWinThread * pThread[2];
pThread[0] = AfxBeginThread(thdReadDirectory,pThis);
pThread[1] = AfxBeginThread(CFileTreeList::thdGetEventFromDB, &(pThis->m_wndNodeCtrl));

for(int i=0;i<2;i++)
{
handles[i] = pThread[i]->m_hThread;
pThread[i]->m_bAutoDelete = false;
}

DWORD nRet = ::WaitForMultipleObjects(2, handles, true, INFINITE);
if(nRet == WAIT_OBJECT_0 )
{
pThis->m_wndNodeCtrl.vMatchEvent();
if(pThis->m_wndNodeCtrl.m_bEvent == true)
{
pThis->OnSelChangeDateCbobox();
pThis->m_wndNodeCtrl.UpdateWindow();
}
}
pThis->m_bReadDone = true;

delete pThread[0];
delete pThread[1];

    return 0;

2011年9月2日 星期五

transparent Dialog

Override OnCtlColor


HBRUSH CDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

if(CTLCOLOR_DLG == nCtlColor)
      {
        pDC->SetBkMode(TRANSPARENT);
        return (HBRUSH)GetStockObject(NULL_BRUSH);
      }
return hbr;
}

2011年8月31日 星期三

LoadCursor


In App class
HCURSOR hCursor = LoadCursor(IDC_CURSOR_TVSET);
:SetCursor(((CApp*)AfxGetApp())->hCursor);
In other class:
HINSTANCE hInstant = AfxGetInstanceHandle();
HCURSOR hCursor = LoadCursor(hInstant,MAKEINTRESOURCE(IDC_CURSOR_TVSET));
::SetCursor(hCursor);

2011年8月4日 星期四

CString<-> TCHAR

TCHAR szMsg[100];
TCHAR *pszMsg;
CString  csMsg;

pszMsg = new TCHAR[100];
memset(szMsg, 0, sizeof(szMsg) );
==================================
TCHAR -> CString

csMsg.Format(_T("%s"), szMsg);

CString ->TCHAR

_stprintf( szMsg, _T("%s"), csMsg.GetBuffer(csMsg.GetLength()));

//or _tcsncpy(szMsg, csMsg.GetBuffer(),_tcslen(csMsg));

pszMsg = csMsg.GetBuffer(csMsg.GetLength());

csMsg.ReleaseBuffer();

delete []pszMsg;
pszMsg = NULL;

2011年6月28日 星期二

CreateWaitableTimer

1. Create

HANDLE hTimer = CreateWaitableTimer(NULL,FALSE,NULL);

2. Set

LARGE_INTEGER liDueTime;
const int nTimerUnitsPerSecond=10*1000*1000; // the unit of timer is 100 nano seconds
// Set the event the first time 2 seconds after calling SetWaitableTimer
 liDueTime.QuadPart= -(STARTTIMERAFTERSECOND * m_nTimerUnitsPerSecond );
int nTimerInterVal = 10;

SetWaitableTimer(hTimer,&liDueTime, (nTimerInterVal*nTimerUnitsPerSecond), NULL, NULL, false);   


3. Use


// Wait for the timer.
if (WaitForSingleObject(hTimer, INFINITE) != WAIT_OBJECT_0)
        printf("WaitForSingleObject failed (%d)\n", GetLastError());
else printf("Timer was signaled.\n");

Detect microphone VC++, waveInGetNumDevs

An easy way to detect the number of waveindevice using waveInGetNumDevs function

#include <Mmsystem.h>
#pragma comment( lib, "Winmm.lib" )

UINT nDevices =     waveInGetNumDevs();

2011年6月14日 星期二

[InstallScript] MsiGetProperty, MsiSetProperty

There's a function to get value from  Property in installscript

MsiGetProperty (hMSI, "ProductCode", szProductCode, numSize);

or set property


MsiSetProperty(hMSI, "NeedScheduleReboot", "1")   ;

this example show how to set reboot after installation

2011年6月13日 星期一

[Installshield] Access Installation Interview in InstallScript MSI project

There's no Installation Interview in project assist panel  within a Installscript MSI project.


To modify which dialog boxes are displayed by modifying the OnFirstUIBefore event in the InstallScript view.

2011年6月2日 星期四

[InstallShield] installscript parse date time and RenameFile

 This example code displays using GetSystemInfo to get system time, using StrGetTokens to parse date, time and RenameFile to rename files.

///////////////////////////////////////////////
// some defines are not showing here

function RenameDBFile(hMSI)
    STRING     szPath,szFileNameDB,szFileNameDBLog ,svResultDB,svResultLog,strDate,strTime,szRenameDB,szRenameDBLog;
    INT       nvDate,nvTime;
    LIST   listDate, listTime;
    STRING  svDdy, svDmn, svDyr, szDelim,szTimeStamp,svHr, svMin, svSec;
  

begin 
   
   
    GetSystemInfo(DATE, nvDate, strDate);
    GetSystemInfo(TIME, nvTime, strTime);
     
 
     
     listDate = ListCreate (STRINGLIST);
     listTime = ListCreate (STRINGLIST);
     StrGetTokens(listDate,strDate,"-");
    ListGetFirstString(listDate,svDmn);
    ListGetNextString(listDate,svDdy);
    ListGetNextString(listDate,svDyr);
    ListDestroy(listDate);
    StrGetTokens(listTime,strTime,":");
    ListGetFirstString(listTime,svHr);
    ListGetNextString(listTime,svMin);
    ListGetNextString(listTime,svSec);
    ListDestroy(listTime);
    szTimeStamp = "."+svDmn + "_" + svDdy + "_" + svDyr + "_" + svHr+ "_"+svMin+ "_"+svSec;
       
    szPath = ProgramFilesFolder + DB_DATA_PATH;   
    szFileNameDB = DB_FILENAME;
    szFileNameDBLog = DB_LOG_FILENAME;   
    szRenameDB = DB_FILENAME + szTimeStamp + ".bak";
    szRenameDBLog = DB_LOG_FILENAME +  szTimeStamp +".bak";
  
  // Set SRCDIR and TARGETDIR for RenameFile
    SRCDIR = szPath;
    TARGETDIR = szPath; 
                            
   
    if(FindFile(szPath, szFileNameDB, svResultDB) = 0 ) then
          RenameFile(szFileNameDB,szRenameDB); 
                 
        endif;
    if(FindFile(szPath, szFileNameDBLog, svResultLog) = 0 ) then
          RenameFile(szFileNameDBLog,szRenameDBLog);
        endif;

end;

Dialog with SysLink control create fail

Using VS2008 SP1, adding a SysLink Control into a dailog and everything is fine in DEBUG mode.
When running in release mode.... something goes wrong, the dialog won't show up and return -1 fail code...
I traced this problem for a while i found it is the problem of SysLink
 
I saw a blog http://twigstechtips.blogspot.com/2010/03/c-dialogs-with-syslink-control-do-not.html 
 
The main reason the Syslink causes the DialogBox() command to fail is because it requires unicode text support, starting from ComCtl32.dll 6. 
 
add this code will solve the problem
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

2011年5月30日 星期一

32 bit application Registry location in x64 Windows

For 64 bit application in  64 bit Windows
HKEY_LOCAL_MACHINE\SOFTWARE\

For 32 bit application
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node

To access or store Registry by Win API, the API will redirect to the corresponding  path

Also the uninstall registry of 32 bit application in win64 is located at

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{product GUID}

2011年5月27日 星期五

ModifyMenu, DeleteMenu

CMenu MainMenu;
MainMenu.LoadMenu (IDR_MENU_NOTIFY);

MainMenu.ModifyMenuW(ID_STREAM_RESTART,MF_BYCOMMAND|MF_STRING,ID_STREAM_RESTART,_T("START"));
MainMenu.DeleteMenu(ID_STREAM_CLOSE,MF_BYCOMMAND);

StartService ,StopService

To StartService or StopService, needs to use OpenSCManager and OpenService API to get SC_HANDLE
//============Stop Service============================
#include "Winsvc.h" // to use SC_HANDLE
SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (schSCManager==0)
    {
        TRACE(_T("KillService OpenSCManager failed"));
    }
    else
    {
        // open the service
        SC_HANDLE schService = OpenService( schSCManager, pName, SERVICE_ALL_ACCESS);
        if (schService==0)
        {
            TRACE(_T("KillService OpenService failed"));
        }
      

      else
        {
            // call ControlService to kill the given service
            SERVICE_STATUS status;
            if(ControlService(schService, SERVICE_CONTROL_STOP, &status))
            {
                CloseServiceHandle(schService);
                CloseServiceHandle(schSCManager);
                return TRUE;
            }


           else
            {
                TRACE(_T("KillService ControlService failed"));
            }
            CloseServiceHandle(schService);
        }
        CloseServiceHandle(schSCManager);
       
    }
   
   
    return FALSE;

//============Start Service===============

SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (schSCManager==0)
    {
        TRACE(_T("RunService OpenSCManager failed\r\n"));
    }
    else
    {
        // open the service
        SC_HANDLE schService = OpenService( schSCManager, pName, SERVICE_ALL_ACCESS);
        if (schService == 0)
        {
            TRACE(_T("RunService OpenService failed"));
        }
        else
        {
            // call StartService to run the service
            if(StartService(schService, 0, (const TCHAR**)NULL))
            {
                CloseServiceHandle(schService);
                CloseServiceHandle(schSCManager);
                return TRUE;
            }
            else
            {
                TRACE(_T("RunService StartService failed"));
            }
            CloseServiceHandle(schService);
        }
        CloseServiceHandle(schSCManager);
       
    }
   

    return FALSE;

QueryServiceStatus

 利用  OpenSCManager, OpenService 這兩個API可以查詢目前服務執行的狀態。
首先要#include "Winsvc.h" 才能使用SC_HANDLE等structure

bool bQueryResult = true;
 // 利用OpenSCManager API 來得到 SC_HANDLE

SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (schSCManager==0)
    {
        TRACE(_T("RunService OpenSCManager failed\r\n"));
    }
    else
    {
 // open the service SC_HANDLE schService = OpenService( schSCManager,
pServiceName, // 這裡的ServiceName是執行檔的名稱(不含.exe),不是服務的顯示名稱
SERVICE_QUERY_STATUS); // 這裡表示執行查詢狀態

        if (schService == 0)
        {
            TRACE(_T("RunService OpenService failed"));
        }
        else
        {
            SERVICE_STATUS ss; // 宣告一個SERVICE_STATUS structure
            if(QueryServiceStatus(schService, &ss))
            {
                if(ss.dwCurrentState == SERVICE_RUNNING)

                    bQueryResult = true;
                else
                    bQueryResult = false;

            }
           
   
            CloseServiceHandle(schService);
            CloseServiceHandle(schSCManager);
        }

    }
    return bQueryResult;

2011年5月26日 星期四

GetFileVersion

利用GetFileVersionInfoSize, GetFileVersionInfo, VerQueryValue這三個API來取得檔案的Version資訊

首先取得執行程式的位置
// get the app path
    TCHAR apppath[MAX_PATH]={0};
    GetModuleFileName(AfxGetInstanceHandle(),apppath,MAX_PATH-1);
    CString csAppPath(apppath);
    int nPos = csAppPath.ReverseFind('\\');
    csAppPath = csAppPath.Left(nPos + 1);
    csAppPath += _T("my.exe");
  
取得版本資訊
  // get version
    DWORD dwLen = 0;
    TCHAR* lpData=NULL;
    BOOL bSuccess = FALSE;
    dwLen = GetFileVersionInfoSize(csAppPath, 0);

   if (0 == dwLen)
    {
      return ;
    }

    lpData =new TCHAR [dwLen+1];

    GetFileVersionInfo(csAppPath, 0, dwLen, lpData);
   
    LPVOID lpBuffer = NULL;
    UINT uLen = 0;

   VerQueryValue(lpData,
              _T("\\StringFileInfo\\040904b0\\FileVersion"),
//040904b0 can be found in resource view->version-> blockheader
             
     /*  properties for query  可以查詢的資訊
    CompanyName
    FileDescription
    FileVersion
    InternalName
    LegalCopyright
    OriginalFilename
    ProductName
    ProductVersion
    Comments
    LegalTrademarks
    PrivateBuild
    SpecialBuild
     */            
              &lpBuffer,
              &uLen);
   
// lpBuffer存有查詢回來的資訊。

   CString csVersion;
   csVersion.Format(_T("%s"),(TCHAR*)lpBuffer);

   m_csVersion += csVersion;
 
delete [] lpData;
// lpBuffer可以不用delete,因為他指向和lpData相同的記憶體空間

2011年5月12日 星期四

[轉錄] Static Class Members may not be Initialized in a Constructor

A common mistake is to initialize static class members inside the constructor body or a member-initialization list like this:
 
class File
{
  private: 
    static bool locked;
  private: 
    File();
  //…
};
File::File(): locked(false) {} //error, static initialization in a member initialization list
Although compilers flag these ill-formed initializations as errors, programmers often wonder why this is an error. Bear in mind that a constructor is called as many times as the number of objects created, whereas a static data member may be initialized only once because it is shared by all the class objects. Therefore, you should initialize static members outside the class, as in this example:
 
class File
{
  private: 
    static bool locked;
  private: 
    File() { /*..*/}
  //…
};

File::locked = false; //correct initialization of a non-const static member
Alternatively, for const static members of an integral type, the Standard now allows in-class initialization:
 
class Screen
{
private:
  const static int pixels = 768*1024; //in-class initialization of const static integral types
public:
  Screen() {/*..*/}
//…
}; 
 
 
原文網址: http://www.devx.com/tips/Tip/13148 
 

2011年4月27日 星期三

HICON; LOADICON

LoadIcon使用方法

HICON   hIcon   =   AfxGetApp()-> LoadIcon(nIconID);
HICON   hIcon   =   LoadIcon(AfxGetApp()-> m_hInstance,   MAKEINTRESOURCE(nIconID)); 

2011年4月15日 星期五

Modeless dialog

如果不想使用DoModal來呼叫建立dialog,可以使用modeless的dialog。
1.呼叫dialog的create,並傳入ID。
ex: CDialog dlg;
dlg.create(IDD_EXAMPLE);

2.在結束時呼叫DestroyWindow(),而不是EndDialog()

ref :http://msdn.microsoft.com/en-us/library/zhk0y9cw%28v=vs.80%29.aspx

2011年4月14日 星期四

Add a new View in MFC MDI

首先加入一個繼承CView的MFC Class : CFlyAwayView;

1. @ Winapp.cpp InitInstance()

    CMultiDocTemplate* pFlyAwayView;
    pFlyAwayView = new CMultiDocTemplate(
        IDR_EXTYPE,
        RUNTIME_CLASS(CDoc),
        RUNTIME_CLASS(CChildFrame), // custom MDI child frame
        RUNTIME_CLASS(CFlyAwayView));
    AddDocTemplate(pFlyAwayView);

pFlyAwayView->OpenDocumentFile(NULL);
//沒有這行View就沒有Active


2. @ MainFrame.cpp
在mainframe中調換view

OnMessageFunction():

CView* pView;
   
    while (pView = MDIGetActive()->GetActiveView())
    {
        if (pView->IsKindOf( RUNTIME_CLASS(CFlyAwayView)))
        {       
         
            AfxMessageBox(_T("hi"));
            break;
        }

            MDINext();
            MDIMaximize(pView);
    }

2011年3月29日 星期二

Installshield Change Dialog Bitmap

To change Dialog Banner or Bitmap of Installshield dialog may reference this article
:http://www.flexerasoftware.com/webdocuments/PDF/DialogBitmaps.pdf

However, a simple way I used is just to override the default banner or bitmap  ibd file

(1) find the default ibd path

[INSTALLSHIELD_PATH]\Redist\Language Independent\OS Independent

ex: C:\Program Files\InstallShield 10.5\Redist\Language Independent\OS Independent

2 ibd files in this folder
IsDialogBanner.ibd ---> this is for the banner on the top of dialog
IsDialogBitmap.ibd----> for bitmap left-side of dialog

(2) Rename 2 ibd files for backup and name the banner / bitmap image to .ibd

Rename IsDialogBanner.ibd to IsDialogBanner_old.ibd or IsDialogBanner.ibd.bak

Name the bitmap or jpg image you want to display to  IsDialogBanner.ibd / IsDialogBitmap.ibd

(3) build the solution

[NOTE] the size of banner is 499x58 pixels and    bitmap is 499x312 pixels

Remember that background color of right side of bitmap should other than black, or you can't see the texts.

Installshield Restart after install/uninstall

在 Installation Designer' tab -> 'Behavior and Logic' -> 'Custom Actions and Sequences' -> 'Sequences' -> 'Installation' -> 'Execute' -> 'ScheduleReboot'
初始值是 ISSCHEDULEREBOOT

設定condition
(1) NOT REMOVE : 安裝完重開機
(2) REMOVE : Uninstall後restart
(3) NOT REMOVE AND REMOVE

如果不想看到重開機的提示
Go to 'Installation Designer' tab -> 'Behavior and Logic' -> 'Property Manager'

加入或修改

name : REBOOTPROMPT
value : Suppress

2011年3月28日 星期一

Installshield Combo box Property

在Installshield中的Dailog新增一個combo box

其中的property必須在"property Manager"中設為全域變數,即為大寫

否則將視為local property

From Installshield help library:

Enter the name of a property that will be set when the end user enters a value into or selects one from this combo box. This property can be unique to this combo box; it need not be present in the Property Manager.

To set a default value for this combo box, make the property is a public property by giving it a name containing only uppercase letters (for example, COMBOPROPERTY), go to the Property Manager and add the public property, and then assign to it the value of the default selection (see Items, above).

2011年3月25日 星期五

SendMessage , PostMessage

SendMessage 和 PostMessage可以將message傳送到一個特定的window
兩者的不同在於 SendMessage必須等到收方做完 PostMessage則是只送

首先要define一個ID 最好是不要重複
#define ID_CHANGE_BMP WM_USER+399

在送方的function
::PostMessage(GetParent()->m_hWnd,ID_CHANGE_BMP,(WPARAM)1,(LPARAM)NULL);

[NOTE]::PostMessage是Windows的function, PostMessage是MFC, 兩者的參數不同
WPARAM是 UINT_PTR。16 bits in Win 3.1, 32 in wind32
LPARAM LONG_PTR, 32

 @收方
Message Map:
ON_MESSAGE(ID_CHANGE_BMP, OnChangeBMP)


LRESULT CIPCamTreeView::OnChangeBMP(WPARAM wParam, LPARAM lParam)
{

    bChangeBmp(wParam);
    return 0;
}

2011年3月21日 星期一

CToolTipCtrl

CToolTipCtrl *m_pOSDToolTip;

OnCreate()
{
    if(!m_pOSDToolTip)
        {
            m_pOSDToolTip= new CToolTipCtrl();
            m_pOSDToolTip->Create(this);
            m_pOSDToolTip->AddTool(m_pFixRatio,_T("Fix Ratio")); // CBitmapButton * m_pFixRatio
            m_pOSDToolTip->AddTool(m_pSnapShot,_T("Snapshot"));
            m_pOSDToolTip->Activate(TRUE);
        }
}

PreTranslateMessage(MSG* pMsg)
{
  
    if(m_bDisplayOSD)
    m_pOSDToolTip->RelayEvent(pMsg);

    return CStatic::PreTranslateMessage(pMsg);
}

2011年3月16日 星期三

Change CStatic Font color

Create a CStatic control
RECT rect;
RECT rcParent;
GetClientRect(&rcParent);
rect.left = rcParent.left;
rect.right = rcParent.right - nBtnWidth;
rect.top = rcParent.top ;
rect.bottom = rcParent.top + nOSDHeight;

if(! m_pCaption)
        {
            m_pCaption = new CStatic();
            bRet |= m_pCaption->Create(NULL, WS_CHILD|WS_VISIBLE|SS_NOTIFY, rect, this , IDC_CAPTIONBAR);//
            if(csCameraName.IsEmpty()) csCameraName = _T("Untitled");
            m_pCaption->SetWindowTextW(csCameraName);
            /*CFont * font = new CFont;
            font->CreateFontW(22,0,0,0,FW_SEMIBOLD,false,false,0,CHINESEBIG5_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH&FF_SWISS,_T("Arial"));
            m_pCaption->SetFont(font);*/
           
        }

Override WM_CTLCOLOR message
HBRUSH CVideo::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    HBRUSH hbr = CStatic::OnCtlColor(pDC, pWnd, nCtlColor);
    COLORREF textColor = RGB(255,255,255);
    COLORREF bkColor = RGB(0,0,0);

       if(nCtlColor == CTLCOLOR_STATIC) //
    {

        pDC->SetTextColor(textColor);
       pDC->SetBkColor(bkColor); // 這裡的background color只限於text周圍, 並不是CStatic所create出來的整個rectangle

    hbr = CreateSolidBrush(bkColor);  // 這樣才會填滿整個retangle
       
    }

return hbr;

其中
  • CTLCOLOR_BTN    Button control
  • CTLCOLOR_DLG    Dialog box
  • CTLCOLOR_EDIT    Edit control
  • CTLCOLOR_LISTBOX    List-box control
  • CTLCOLOR_MSGBOX    Message box
  • CTLCOLOR_SCROLLBAR    Scroll-bar control
  • CTLCOLOR_STATIC    Static control


 或者可以指定要改哪個ID
    if(pWnd->GetDlgCtrlID() ==IDC_CAPTIONBAR)
    {
       
        pDC->SetTextColor(textColor);
        pDC->SetBkColor(bkColor);

    }

     return hbr;
}

OnEraseBkgnd

OnEraseBkgnd()
{

    pDC->SetBkColor(BKCOLOR);//BKCOLOR
    CRect rect;
    GetClientRect(rect);
    CBrush bkColor(RGB(190,190,190));
    pDC->FillRect(&rect,&bkColor);
}
Override :WM_ERASEBKGND message
利用FillRect函式在視窗大小改變時 將background重畫。

2011年3月11日 星期五

[MFC] Get Applcation file name

TCHAR szPath[MAX_PATH];
if( !GetModuleFileName(NULL, szPath, MAX_PATH ))
{
 printf("GetModuleFileName failed (%d)\n", GetLastError());
 return _T("");
}
CString strPath(szPath);
int nPos = strPath.ReverseFind('\\');
strPath = strPath.Left(nPos + 1);
或者
TCHAR szPathName[MAX_PATH] = { 0 };
TCHAR szDrive[_MAX_DRIVE] = { 0 };
TCHAR szDir[_MAX_DIR] = { 0 };
TCHAR szFname[_MAX_FNAME] = { 0 };
TCHAR szExt[_MAX_EXT] = { 0 };
(void)::GetModuleFileName( NULL, szPathName, MAX_PATH );
_splitpath( szPathName, szDrive, szDir, szFname, szExt );

2011年2月21日 星期一

將 data(struct) 寫到Registry。

1. Set

    HKEY hkFolder;
    DWORD dwDisposition = REG_CREATED_NEW_KEY;

    if(!m_vctNode.empty()) m_vctNode.clear();

    if (ERROR_SUCCESS == ::RegCreateKeyEx(HKEY_CURRENT_USER, REGISTSUBFOLDER, NULL,  _T("NODEITEM"),
                           REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkFolder, &dwDisposition))
    {
        DWORD nSize = vctpNode.size();
        NODEITEM * pNode = new NODEITEM[nSize];
        for(int i=0;i<vctpNode.size();i++)
        {
            m_vctNode.push_back(*(vctpNode[i]));
            pNode[i] = (*(vctpNode[i]));

        }
       
        RegSetValueEx(hkFolder, _T("NODEITEM"), NULL, REG_BINARY, (BYTE*) pNode, nSize * sizeof(NODEITEM));
        delete [] pNode;
    }
    RegCloseKey(hkFolder);

2. Get

    vGetAppCacheFolder();
    HKEY hkFolder;
    DWORD cbData = 0;
    DWORD nType = REG_BINARY;
    bool bResult = false;
   
    NODEITEM *pNode = NULL;
    LONG nRet1 = RegOpenKey(HKEY_CURRENT_USER, REGISTSUBFOLDER, &hkFolder);
    cbData = 0;
    LONG nRet2 = RegQueryValueEx(hkFolder, _T("NODEITEM"), NULL, &nType, (BYTE*)pNode, &cbData);
    DWORD nApplySize = cbData/sizeof(NODEITEM);
    pNode = new NODEITEM[nApplySize];
    memset(pNode, 0, nApplySize);
    nRet2 = RegQueryValueEx(hkFolder, _T("NODEITEM"), NULL, &nType, (BYTE*)pNode, &cbData);

    if ( nRet1 == ERROR_SUCCESS && nRet2  == ERROR_SUCCESS )
    {
        m_vctNode.clear();
        int nSize =  cbData/sizeof(NODEITEM);
        for (int ci=0; ci < nSize; ci++)
        {           
            try{

                m_vctNode.push_back((pNode[ci]));
            }
            catch(exception* e){
                delete e;
                m_vctNode.clear();
                delete [] pNode;
                return false;
            }       
        }

        bResult = true;
    }else
    {
        FORMATMESSAGE(nRet2);
    }
    try
    {
        delete [] pNode;
    }catch(exception* e)
    {
        m_vctNode.clear();
        delete e;
    }
    RegCloseKey(hkFolder);
    return bResult;

2011年2月17日 星期四

vector::erase和iterator的問題

vector 在erase後,原本的iterator會失效 (被移除了)
所以在使用for-loop + erase要注意

std::vector::erase()會回傳一個有效的iterator


example::

std::vector<int> myVector;
std::vector<int>::iterator it;

for(it = myVector.begin(); it !=myVector.end();)
{
   if(*it != 1)
         it = myVector.erase(it);
   else
      ++it;

}

2011年2月16日 星期三

How To Check If Computer Is Running A 32 Bit or 64 Bit Operating System in Registry

1.HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\0


Identifier         REG_SZ                     x86 Family 6 Model 14 Stepping 12
Platform ID    REG_DWORD          0x00000020(32)

2. HKLM\SYSTEM\CurrentCongtrolSet\Control\Session Manager\Envirornment

PROCESSOR_ARCHITECTURE   REG_SZ         x86

3.HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion 

 BuildLabEx  REG_SZ 7600.16695.x86fre.win7_gdr.101026-1503

2011年2月14日 星期一

CPen

CPen pen(PS_SOLID,2,RGB(192,192,192));
CPen *oldPen;  
oldPen = pDC->SelectObject(&pen1);
pDC->MoveTo(10,10);\\ 起點   
pDC->LineTo(200,20);\\ 線的終點   
pDC->SelectObject(oldPen);

example:

for(int i=0;i<5;i++)
    {
            CPen* pPen = &Pen;
            CPen *pOldPen =    pDC->SelectObject( pPen );
            pDC->MoveTo(0,row);
            pDC->LineTo(nWidth,row);
            pDC->SelectObject( &pOldPen );
            row+=20;
    }

2011年2月9日 星期三

取消CDockablePane的Close button (修改CDockablePane的風格)

1. OnCreate


the AFX_DEFAULT_DOCKING_PANE_STYLE defined is
static const DWORD AFX_DEFAULT_DOCKING_PANE_STYLE = AFX_CBRS_FLOAT | AFX_CBRS_CLOSE | AFX_CBRS_RESIZE | AFX_CBRS_AUTOHIDE;

把AFX_CBRS_CLOSE移除即可

m_wndClassView.Create( strFileViewWnd, this, CRect( 0, 0, 200, 200 ), TRUE, ID_PANE_FILEVIEW_WND, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_LEFT | CBRS_FLOAT_MULTI, AFX_CBRS_REGULAR_TABS, AFX_CBRS_FLOAT | AFX_CBRS_RESIZE | AFX_CBRS_AUTOHIDE )  ;


2. GetControlBarStyle() and SetControlBarStyle( dwStyle )

DWORD dwStyle = m_wndClassView.GetControlBarStyle();
    dwStyle &= ~( AFX_CBRS_CLOSE | AFX_CBRS_RESIZE | AFX_CBRS_FLOAT| AFX_CBRS_AUTOHIDE);
    m_wndClassView.SetControlBarStyle( dwStyle );

2011年2月8日 星期二

CTime CString 互轉

CString -> CTime

TCHAR *tcValidTimeFrom, *tcValidTimeTo;
int iHour, iMinute,iSecond;

 tcValidTimeFrom = (TCHAR*)(LPCTSTR) csValidTimeFrom;                                                        _stscanf(tcValidTimeFrom, _T("%d:%d:%d"), &iHour, &iMinute, &iSecond);
CTime ctimeValidFrom(1970,1,1,iHour,iMinute,iSecond);

CTime -> CString


CTime time;
CString csDate;
CString csDate = time.Format(_T("%Y\%m\%d"));