面对现实,超越自己
逆水行舟,不进则退
posts - 269,comments - 32,trackbacks - 0
MFC 类型转换

一、CString与LPSTR、LPCSTR、string、 char*相互转换

1. CString转换成LPSTR:
方法一:   
1  CString strFileName;    
2  LPSTR lpStr = strFileName.GetBuffer();  
3  strFileName.ReleaseBuffer();  
方法二:     
1 CString strFileName;   
2  LPSTR lpStr = (LPSTR)(LPCSTR)strFimeName;
3 

2. LPSTR转换成CString:

1 LPSTR lpStr = _T("TestStr");   
2 CString str(lpStr);   
3 //注意:CString和LPCSTR可直接转换,如下:   
4 CString str;   
5 LPCSTR lpcStr = (LPCSTR)str;

CString转换成LPSTR:
CString strTemp;
LPTSTR pSterTemp = strTemp.GetBuffer();  //这会为pSetTemp指向的字符串分配内存,同时会把strTemp的内容拷贝下来。。
strTemp.ReleaseBuffer();  //must call this funtion. 归还内存给操作系统。

或:
LPTSTR pSterTemp = (LPTSTR)(LPCSTR)strTemp;

3.string 转 CString  
1 CString.format("%s"string.c_str());

4.CString 转 string 

1 string s(CString.GetBuffer(CString.GetLength()));

5. CString转char*

(1)传给未分配内存的const char* (LPCTSTR)指针.      

1 CString cstr(asdd);
2 const char* ch = (LPCTSTR)cstr;
3 //ch指向的地址和cstr相同。但由于使用const保证ch不会修改,所以安全.

 

(2)传给未分配内存的指针.   

CString cstr = "ASDDSD";
char *ch = cstr.GetBuffer(cstr1.GetLength() + 1);
cstr.ReleaseBuffer();
//修改ch指向的值等于修改cstr里面的值.
//PS:用完ch后,不用delete ch,因为这样会破坏cstr内部空间,容易造成程序崩溃.

(3)第二种用法。把CString 值赋给已分配内存的char *.

1 CString cstr1 = "ASDDSD";
2 int strLength = cstr1.GetLength() + 1;
3 char *pValue = new char[strLength];
4 strncpy(pValue, cstr1, strLength);

(4)第三种用法.把CString 值赋给已分配内存char[]数组.

1 CString cstr2 = "ASDDSD";
2 int strLength1 = cstr1.GetLength() + 1;
3 char chArray[100];
4 memset(chArray,0sizeof(bool* 100); //将数组的垃圾内容清空.

 6、char * 转 CString  

1 CString.format("%s"char*);

      
二、string与char*转换

1、char * 转 string 

1 string s(char *);

 2、string 转 char *        

1 char *= string.c_str();


三、CString转换到TCHAR *
1、使用强制转换。例如:

1 CString theString( "This is a test" );
2 LPTSTR lpsz =(LPTSTR)(LPCTSTR)theString;

2、使用strcpy。例如:

1 CString theString( "This is a test" );
2 LPTSTR lpsz = new TCHAR[theString.GetLength()+1];
3 _tcscpy(lpsz, theString); 
4 
5 //需要说明的是,strcpy(或可移值Unicode/MBCS的_tcscpy)的第二个参数是 const wchar_t* (Unicode)或const char* (ANSI),系统编译器将会自动对其进行转换。

3、使用CString::GetBuffer。例如:

1 CString s(_T("This is a test "));
2 LPTSTR p = s.GetBuffer();
3 // 在这里添加使用p的代码
4 if(p != NULL) *= _T('\0');
5     s.ReleaseBuffer(); 
6 // 使用完后及时释放,以便能使用其它的CString成员函数


四、stringwstring

1     wchar_t wcs[100], wc;
2 
3     string testStr1="1234567890";
4 
5     setlocale(LC_CTYPE, "");  //很重要,没有这一句,转换会失败
6 
7     mbstowcs(wcs, testStr1.c_str(), 99);
8 
9     wstring testStr(wcs);
  
#include <string>
std::string ws2s(const std::wstring& ws)
{
    std::string curLocale = setlocale(LC_ALL, NULL);        // curLocale = "C";
    setlocale(LC_ALL, "chs");
    const wchar_t* _Source = ws.c_str();
    size_t _Dsize = 2 * ws.size() + 1;
    char *_Dest = new char[_Dsize];
    memset(_Dest,0,_Dsize);
    wcstombs(_Dest,_Source,_Dsize);
    std::string result = _Dest;
    delete []_Dest;
    _Dest = NULL;
    setlocale(LC_ALL, curLocale.c_str());
    return result;
}

std::wstring s2ws(const std::string& s)
{
    setlocale(LC_ALL, "chs"); 
    const char* _Source = s.c_str();
    size_t _Dsize = s.size() + 1;
    wchar_t *_Dest = new wchar_t[_Dsize];
    wmemset(_Dest, 0, _Dsize);
    mbstowcs(_Dest,_Source,_Dsize);
    std::wstring result = _Dest;
    delete []_Dest;
    _Dest = NULL;
    setlocale(LC_ALL, "C");
    return result;
}

C语言库函数名: atoi   功 能: 把字符串转换成整型数
函数名: atof   功 能: 把字符串转换成浮点数

CString与Byte数组相互转换

 CString cs1 = "gettruckpos";

 byte buf[200];

 memcpy(buf,cs1.GetBuffer(cs1.GetLength()),cs1.GetLength());  //将cstring放入byte数组

 CString *pPhoneNum =new CString((char*)buf, cs1.GetLength()); //将byte数组转换成cstring

 CString cs2 = *pPhoneNum;

int转byte
//int转byte
void  intToByte(int i,byte *bytes,int size = 4)
{
    byte[] bytes = new byte[4];
    memset(bytes,0,sizeof(byte) *  size);
    bytes[0] = (byte) (0xff & i);
    bytes[1] = (byte) ((0xff00 & i) >> 8);
    bytes[2] = (byte) ((0xff0000 & i) >> 16);
    bytes[3] = (byte) ((0xff000000 & i) >> 24);
    return ;
 }

BYTE*  IntToBytes(int nNum, BOOL isHighFirst, BYTE *pVal)
{
    BYTE result[4] = {0};

    if (isHighFirst)
    {
        result[0]  = (BYTE)(nNum >> 24 & 0xff);
        result[1]  = (BYTE)(nNum >> 16 & 0xff);
        result[2]  = (BYTE)(nNum >> 8 & 0xff);
        result[3]  = (BYTE)(nNum & 0xff);
    }
    else
    {
        result[3]  = (BYTE)(nNum >> 24 & 0xff);
        result[2]  = (BYTE)(nNum >> 16 & 0xff);
        result[1]  = (BYTE)(nNum >> 8 & 0xff);
        result[0]  = (BYTE)(nNum & 0xff);
    }

    memcpy(pVal, result, 4);

    return result;
}

byte转int
//byte转int
int bytesToInt(byte* bytes,int size = 4) 
{
    int addr = bytes[0] & 0xFF;
    addr |= ((bytes[1] << 8) & 0xFF00);
    addr |= ((bytes[2] << 16) & 0xFF0000);
    addr |= ((bytes[3] << 24) & 0xFF000000);
    return addr;
 }

CString转 wchar_t*
wchar_t * CCommonFun::ConvertCStringToWchar_t(CString &str)
{
    CString sTemp = str;
    const char* CStr = (LPCTSTR)sTemp;

    size_t len = strlen(CStr) + 1;
    size_t converted = 0;
    wchar_t *WStr;
    WStr = (wchar_t*)malloc(len*sizeof(wchar_t));
    mbstowcs_s(&converted, WStr, len, CStr, _TRUNCATE);

    return WStr;
}
 注意:可以在调用的地方释放分配的内存,如果遇到汉子转换乱码问题可以在转换前使用setlocale(LC_ALL, "chs")或者setlocale(LC_ALL,"zh_CN.UTF-8")进行设置

wchar_t*转CString
CString  CTestTextToPicDlg::ConvertWchar_tToCString(const wchar_t* WStr)
{
    size_t len = wcslen(WStr) + 1;
    size_t converted = 0;
    char *CStr;
    CStr=(char*)malloc(len*sizeof(char));
    wcstombs_s(&converted, CStr, len, WStr, _TRUNCATE);
    CString sTemp;
    sTemp.Format("%s", CStr);

    free(CStr);
    CStr = NULL;

    return sTemp;
}

TCHAR和char的区别:

C++支持两种字符串,即常规的ANSI编码(使用""包裹)和Unicode编码(使用L""包裹),这样对应的就有了两套字符串字符串处理函数,比如:strlen和wstrlen,分别用于处理两种字符串。

 

由于字符编码的不同,在C++中有三种对于字符类型:char, wchar_t , TCHAR。其实TCHAR不能算作一种类型,他紧紧是一个宏。我们都知道,宏在预编译的时候会被替换成相应的内容。TCHAR 在使用多字节编码时被定义成char,在Unicode编码时定义成wchar_t。
如果你希望同时为ANSI和Unicode编译的源代码,那就要include TChar.h。TCHAR是定义在其中的一个宏,它视你是否定义了_UNICODE宏而定义成char或者wchar_t。如果你使用了TCHAR,那么就不应该使用ANSI的strXXX函数或者Unicode的wcsXXX函数了,而必须使用TChar.h中定义的_tcsXXX函数。另外,为了解决刚才提到带“L”的问题,TChar.h中定义了一个宏:“_TEXT”。

 以strcpy函数为例子,总结一下:
 .如果你想使用ANSI字符串,那么请使用这一套写法:
 char szString[100];
 strcpy(szString,"test");
 .如果你想使用Unicode字符串,那么请使用这一套:
 wchar_t szString[100];
 wcscpyszString,L"test");
 .如果你想通过定义_UNICODE宏,而编译ANSI或者Unicode字符串代码:
 TCHAR szString[100];
 _tcscpy(szString,_TEXT("test"));

使用TCHAR系列方案编写程序
    TCHAR是一种字符串类型,它让你在以MBCS和UNNICODE来build程序时可以使用同样的代码,不需要使用繁琐的宏定义来包含你的代码。 
      TCHAR的引入,主要是在Tchar.h文件中,该文件包含这方面的重要的定义信息。
      对于包含了对str函数或wcs函数进行显式调用的代码来说,无法非常容易地同时为ANSI和Unicode对这些代码进行编译。本章前面说过,可以创建同时为ANSI和Unicode进行编译的单个源代码文件。若要建立双重功能,必须包含TChar.h文件,而不是包含String.h文件。
      TChar.h文件的唯一作用是帮助创建ANSI/Unicode通用源代码文件。它包含你应该用在源代码中的一组宏,而不应该直接调用str函数或者 wcs函数。如果在编译源代码文件时定义了_UNICODE,这些宏就会引用wcs这组函数。如果没有定义_UNICODE,那么这些宏将引用str这组宏。
      TCHAR的定义如下:
      #ifdef UNICODE
      typedef wchar_t TCHAR;
      #else
      typedef char TCHAR;
      #endif
      所以用MBCS来build时,TCHAR是char,使用UNICODE时,TCHAR是wchar_t。
      还有一个宏来处理定义Unicode字符串常量时所需的L前缀。
      #ifdef UNICODE
      #define _T(x) L##x
      #define _TEXT(x) L##x
      #define __T(x) L##x
      #else
      #define _T(x) x
      #define _TEXT(x) x
      #define __T(x) x
      #endif
     ## 是一个预处理操作符,它可以把两个参数连在一起。如果你的代码中需要字符串常量,在它前面加上_T宏。如果你使用Unicode来build,它会在字符串常量前加上L前缀。
      TCHAR szNewText[] = _T("we love Bob!");
    _UNICODE宏用于C运行期头文件,而UNICODE宏则用于Windows头文件。当编译源代码模块时,通常必须同时定义这两个宏。
  像是用宏来隐藏SetWindowTextA/W的细节一样,还有很多可以供你使用的宏来实现str***()和_mbs***()等字符串函数。例如,你可以使用_tcsrchr宏来替换strrchr()、_mbsrchr()和wcsrchr()。_tcsrchr根据你预定义的宏是_MBCS还是 UNICODE来扩展成正确的函数,就象SetWindowText所作的一样。
   不仅str***()函数有TCHAR宏。其他的函数如, _stprintf(代替sprinft()和swprintf()),_tfopen(代替fopen()和_wfopen())。 MSDN中"Generic-Text Routine Mappings."标题下有完整的宏列表。

QT类型转换

QString转char*

Qstring  str;

char*  ch;

QByteArray ba = str.toLatin1();    

ch=ba.data();

 

这样就完成了QString向char*的转化。经测试程序运行时不会出现bug

注意第三行,一定要加上,不可以str.toLatin1().data()这样一部完成,可能会出错。

补充:以上方法当QString里不含中文时,没有问题,但是QString内含有中文时,转换为char*就是乱码,采用如下方法解决:

方法1:

添加GBK编码支持:

#include <QTextCodec>

QTextCodec::setCodecForTr(QTextCodec::codecForName("GBK"));
QTextCodec::setCodecForLocale(QTextCodec::codecForName("GBK"));

然后改变上面的第三行为:QByteArray ba = str.toLoacl8Bit();      toLoacl8Bit支持中文

方法2:

先将QString转为标准库中的string类型,然后将string转为char*,如下:

std::string str = filename.toStdString();

const char* ch = str.c_str();

 

posted @ 2012-04-06 17:08 王海光 阅读(977) | 评论 (0)编辑 收藏
转自:http://apps.hi.baidu.com/share/detail/6937479

对于类似从给定的文本中,查找其中最长的重复子字符串的问题,可以采用“后缀数组”来高效地完成此任务。后缀数组使用文本本身和n个附加指针(与文本数组相应的指针数组)来表示输入文本中的n个字符的每个子字符串。
    首先,如果输入字符串存储在c[0..n-1]中,那么就可以使用类似于下面的代码比较每对子字符串:
    maxlen = -1
    for i = [0, n)
        for j = (i, n)
            if (thislen = comlen(&c[i], &c[j])) > maxlen
                maxlen = thislen
                maxi = i
                maxj = j
    当作为comlen函数参数的两个字符串长度相等时,该函数便返回这个长度值,从第一个字符开始:
    int comlen(char *p, char* q)
        i = 0
        while *p && (*p++ = *q++)
            i++
        return i
    由于该算法查看所有的字符串对,所以它的时间和n的平方成正比。下面便是使用“后缀数组”的解决办法。
    如果程序至多可以处理MAXN个字符,这些字符被存储在数组c中:
    #define MAXN 5000000
    char c[MAXN], *a[MAXN];
    在读取输入时,首先初始化a,这样,每个元素就都指向输入字符串中的相应字符:
    while (ch = getchar()) != EOF
  a[n] = &c[n];
  c[n++] = ch;
 c[n] = 0 //将数组c中的最后一个元素设为空字符,以终止所有字符串。
 这样,元素a[0]指向整个字符串,下一个元素指向以第二个字符开始的数组的后缀,等等。如若输入字符串为"banana",该数组将表示这些后缀:
 a[0]:banana
 a[1]:anana
 a[2]:nana
 a[3]:ana
 a[4]:na
 a[5]:a
 由于数组a中的指针分别指向字符串中的每个后缀,所以将数组a命名为"后缀数组"
 第二,对后缀数组进行快速排序,以将后缀相近的(变位词)子串集中在一起
 qsort(a, n, sizeof(char*), pstrcmp)后
 a[0]:a
 a[1]:ana
 a[2]:anana
 a[3]:banana
 a[4]:na
 a[5]:nana
 第三,使用以下comlen函数对数组进行扫描比较邻接元素,以找出最长重复的字符串:
 for i = [0, n)
     if comlen(a[i], a[i+1]) > maxlen
         maxlen = comlen(a[i], a[i+1])
         maxi = i
 printf("%.*s/n", maxlen, a[maxi])
 由于少了内层循环,只是多了一次排序,因此该算法的运行时间为O(n logn). 

完整代码如下:
 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 
 5 #define MAXCHAR 5000 //最长处理5000个字符
 6 
 7 char c[MAXCHAR], *a[MAXCHAR];
 8 
 9 int comlen( char *p, char *q )
10 {
11     int i = 0;
12     while*&& (*p++ == *q++) )
13         ++i;
14     return i;
15 }
16 
17 int pstrcmp( const void *p1, const void *p2 )
18 {
19     return strcmp( *(char* const *)p1, *(char* const*)p2 );
20 }
21 
22 int main( )
23 {
24     char ch;
25     int n=0;
26     int i, temp;
27     int maxlen=0, maxi=0;
28     printf("Please input your string:\n");
29     while( (ch=getchar())!='\n' )
30    {
31         a[n]=&c[n];
32         c[n++]=ch;
33     }
34     c[n]='\0';
35     qsort( a, n, sizeof(char*), pstrcmp );
36     for(i=0; i<n-1++i )
37    {
38         temp=comlen( a[i], a[i+1] );
39         if( temp>maxlen )
40         {
41             maxlen=temp;
42             maxi=i;
43         }
44     }
45     printf("%.*s\n",maxlen, a[maxi]);
46     system("PAUSE");
47     return 0;
48 }

posted @ 2012-03-30 13:03 王海光 阅读(701) | 评论 (0)编辑 收藏

编程珠玑第二版快速排序

 1 qsort4(0, n-1);
 2 isort3();
 3 
 4 void qsort4(l, u)
 5 {  
 6      if (u - l < cutoff)               //cutoff是一个小整数,如果要排序的数组很小,可以用插入排序,速度更快
 7         return;
 8        swap(L, randint(l, u))      //将第一个数据与后面的数据随即交换,避免要排序的数据已是升序排列或者第一个数据很小
 9        t = x[l];                            //t为中间元素,所有数据与其进行比较,小于t的放到左边,大于t的放到右边
10        i = l;
11       j = u+1;
12       loop
13               do 
14               {
15                      i++;
16               } while (i <= u && x[i] < t);     //从第二个数据开始比较,遇到大于t的数据终止循环
17 
18               do 
19               {
20                      j--;
21                } while (x[j] > t);     //从最后一个数据进行比较,遇到小于t的终止循环
22 
23               if (i > j)          //如果i>j,数据分组成功,跳出循环
24                      break;
25               temp = x[i];    //交换上面两个循环终止时的数据
26               x[i] = x[j];
27               x[j] = temp;
28 
29        swap(l, j);           //交换x[i]与x[j]的值,分组完成
30        qsort4(l, j-1);     //排序小于t的数据
31        qsort4(j+1, u);   //排序大于t的数据 
32 }
33 
34 void isort3() //插入排序,当排序的数据很少时可以用此排序
35 {
36        int i,j;
37        for i = [l, n)
38            t = x[i];
39            for (j=i; j>0 && x[j-1]>t; j--)
40            {
41                   x[j] = x[j-1];
42            }
43            x[j] = t;
44   }


转自:http://www.cppblog.com/humanchao/archive/2008/08/18/59241.html

void QuickSort(int* pData,int left,int right)
{
    
int i = left, j = right;
    
int middle = pData[(left+right)/2];        // midlle value
    int iTemp;
    
do
    {    
        
while (pData[i] < middle && i < right)            i++;
        
while (pData[j] > middle && j > left)            j--;
        
if (i < j)                            // swap
        {
            iTemp    
= pData[i];
            pData[i] 
= pData[j];
            pData[j] 
= iTemp;
            i
++;            j--;
        } 
        
else if (i == j)
        {
            i
++;            j--;
        }
    } 
while (i < j);

    
if (left  < j)        QuickSort(pData,left,j);
    
if (right > i)        QuickSort(pData,i,right);
}

 

堆排序实现原理

转自:http://www.nowamagic.net/algorithm/algorithm_HeapSortStudy.php


堆排序
C语言描述

  
 1 // array是待调整的堆数组,i是待调整的数组元素的位置,nlength是数组的长度 
 2   void HeapAdjust(int array[],int i,int nLength) //本函数功能是:根据数组array构建大根堆 
 3   { 
 4         int nChild; 
 5         int nTemp; 
 6         for (nTemp = array[i]; 2 * i + 1 < nLength; i = nChild) 
 7         { 
 8               // 子结点的位置=2*(父结点位置)+ 1 
 9               nChild = 2 * i + 1
10               // 得到子结点中较大的结点 
11               if (nChild < nLength - 1 && array[nChild + 1> array[nChild]) 
12               ++nChild; 
13               // 如果较大的子结点大于父结点那么把较大的子结点往上移动,替换它的父结点 
14               if (nTemp < array[nChild]) 
15               { 
16                     array[i]= array[nChild]; 
17               } 
18               else // 否则退出循环 
19               { 
20                     break
21               } 
22               // 最后把需要调整的元素值放到合适的位置 
23               array[nChild]= nTemp; 
24         } 
25   } 
26   // 堆排序算法 
27   void HeapSort(int array[],int length) 
28   { 
29           // 调整序列的前半部分元素,调整完之后第一个元素是序列的最大的元素 
30         for (int i = length / 2 - 1; i >= 0--i) 
31         { 
32               HeapAdjust(array,i,length); 
33         } 
34         // 从最后一个元素开始对序列进行调整,不断的缩小调整的范围直到第一个元素 
35         for (int i = length - 1; i > 0--i) 
36         { 
37               // 把第一个元素和当前的最后一个元素交换, 
38               // 保证当前的最后一个位置的元素都是在现在的这个序列之中最大的 
39               Swap(&array[0],&array[i]); 
40               // 不断缩小调整heap的范围,每一次调整完毕保证第一个元素是当前序列的最大值 
41               HeapAdjust(array,0,i); 
42         } 
43   } 
堆排序算法(C++描述)
 1 #define MAX 100//数据元素的最大个数 
 2   typedef struct 
 3   { 
 4         int r[MAX]; 
 5         int length; 
 6   }SqList;//定义一个线性表用于存放数据元素 
 7   void HeapAdjust(SqList &L,int s,int m) 
 8   {
 9             //已知L.r[sm]中记录除L.r[s]外均满足堆的定义,本函数用于使L.r[sm]成为一个大顶堆 
10         int j; 
11         int e=L.r[s]; 
12         for(j=2*s;j<=m;j*=2
13         { 
14               if(j<M&&L.R[J]<L.R[J+1]) ++j; 
15               if(e>=L.r[j]) break
16               L.r[s]=L.r[j]; 
17               s=j; 
18         } 
19         L.r[s]=e; 
20   } 
21   void HeapSort(SqList &L) 
22   {
23             //对顺序表L进行堆排序 
24         int i,e; 
25         for(i=L.length/2;i>0;i--
26               HeapAdjust(L,i,L.length); 
27         for(i=L.length;i>1;i--
28         {
29                   //将大顶堆的顶记录和最后一个记录相互交换 
30               e=L.r[1]; 
31               L.r[1]=L.r[i]; 
32               L.r[i]=e; 
33               HeapAdjust(L,1,i-1); 
34         } 
35   } 
posted @ 2012-03-30 12:47 王海光 阅读(586) | 评论 (0)编辑 收藏
     摘要: 一、查看是否有优盘插入 Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->1 #define MESSAGEBOX_TITLE    "标题"2 #define PLEAS...  阅读全文
posted @ 2012-03-14 14:01 王海光 阅读(1035) | 评论 (0)编辑 收藏
转自:http://blog.csdn.net/blueblood7/article/details/7193573


用 NSIS制作64位安装包 步骤

1、在安装脚本的开始处定义 LIBRARY_X64。

!include "MUI.nsh"
!include "Library.nsh"

;如果做32位安装包就把下句注释。
!define LIBRARY_X64

 

2、注册COM组件,需包含Library.nsh,用宏InstallLib/UnInstallLib 代替RegDLL/UnRegDLL。

;RegDLL "$SYSDIR\ComName.dll"
!insertmacro InstallLib REGDLL NOTSHARED REBOOT_NOTPROTECTED "LocalPath\ComName.dll" "$SYSDIR\ComName.dll" $SYSDIR

;UnRegDLL "$SYSDIR\ComName.dll"
!insertmacro UnInstallLib REGDLL NOTSHARED REBOOT_NOTPROTECTED "$SYSDIR\ComName.dll"

 

3、在调用涉及注册表的函数前用 SetRegView 64,后用 SetRegView lastused。

!ifdef  LIBRARY_X64
 SetRegView 64
!endif

 WriteRegStr ...
 WriteRegStr ...
 WriteRegStr ...

!ifdef  LIBRARY_X64
 SetRegView lastused
!endif 

SetRegView用户手册:
在 Windows x64 上共有2种查看方式。一种用于 32-bit 应用程序,另一种用于 x64 应用程序。默认情况下,32-bit 应用程序运行在 x64 系统的 WOW64 模式下时,只允许使用 32-bit 查看方式。使用 SetRegView 64 将允许安装程序在 x64 中访问注册表键值。

它将影响
DeleteRegKey,
DeleteRegValue,
EnumRegKey,
EnumRegValue,
ReadRegDWORD
,
ReadRegStr
,
WriteRegBin
,
WriteRegDWORD
,
WriteRegStr
,
WriteRegExpandStr

它不会影响 InstallDirRegKey。另外,在函数 .onInit 中也可使用 ReadRegStr 读取注册表。

SetRegView 32
ReadRegStr $0 HKLM Software\Microsoft\Windows\CurrentVersion ProgramFilesDir
DetailPrint $0 # prints C:\Program Files (x86)
SetRegView 64
ReadRegStr $0 HKLM Software\Microsoft\Windows\CurrentVersion ProgramFilesDir
DetailPrint $0 # prints C:\Program Files
Function .onInit
  SetRegView 64
  ReadRegStr $INSTDIR HKLM Software\NSIS ""
  SetRegView 32
FunctionEnd

4、在调用涉及目标机器上系统目录(即$SYSDIR)的函数前用 ${DisableX64FSRedirection}。

在安装包的第一个Section中调用一次即可。
!ifdef  LIBRARY_X64
 ${DisableX64FSRedirection}
!endif 

 

5、在64位系统上 $PROGRAMFILES64 表示“Program Files”, $PROGRAMFILES 表示 “Program Files (x86)”。

可以在安装脚本的开始处定义一个常量,
!ifdef LIBRARY_X64
!define PROGRAM_FILES_MAP  $PROGRAMFILES64
!else
!define PROGRAM_FILES_MAP  $PROGRAMFILES
!endif
以后直接用 ${PROGRAM_FILES_MAP} 代替 $PROGRAMFILES。

 

6、在.onInit 和 un.onInit 中判断一下,如果安装包是在32位操作系统上运行,则停止安装。

可创建一个宏,然后在需要的地方插入。
!macro TIP_WHEN_AMD64_INSTALLER_RUNAT_X86
 !ifdef LIBRARY_X64
  ${If} ${RunningX64}
  ${else}
     MessageBox MB_OK|MB_ICONINFORMATION "请在64位操作系统下运行。"
   Abort
  ${EndIf}
 !endif
!macroend

Function .onInit
 !insertmacro TIP_WHEN_AMD64_INSTALLER_RUNAT_X86
 SetShellVarContext all  ;安装到所有用户下,current 表示安装到当前用户下, all 表示所有用户下。
FunctionEnd

Function un.onInit
 !insertmacro TIP_WHEN_AMD64_INSTALLER_RUNAT_X86
 SetShellVarContext all
FunctionEnd

 

备注:
1、在 NSIS 中的条件编译是 !开头,不是 #开头,如!ifdef。
2、对COM组件,我认为应该是使用 NOTSHARED 方式注册。
3、可以做个批处理文件,一次性生成32位/64位的安装包。
 如 x.bat
 rem "记得要把安装脚本中的 !define LIBRARY_X64 注释掉,否则不能生成32位安装包。"
 makensis .\myinstaller.nsi
 makensis /DLIBRARY_X64 .\myinstaller.nsi
 pause
 

posted @ 2012-03-08 12:51 王海光 阅读(6035) | 评论 (0)编辑 收藏

 

 1 //获取xml文件路径
 2 CString sXmlPath = CCommonFun::GetExecutablePath() + "420120223165116971.pcl.xml";
 3  
 4 TiXmlDocument* pXmlDoc = new TiXmlDocument(sXmlPath);
 5 //导入xml文件
 6 pXmlDoc->LoadFile();
 7 
 8 //获取根节点
 9 TiXmlElement *xmlRootElement = pXmlDoc->RootElement();
10 
11 //创建新节点
12 TiXmlElement *x1 = new TiXmlElement("WaterMarks");
13 xmlRootElement->LinkEndChild(x1);
14 
15 //创建新节点下的子节点
16 TiXmlElement *nameElement = new TiXmlElement("WaterMark");
17 //设置子节点属性
18 nameElement->SetAttribute("copies""1");
19 nameElement->SetAttribute("type""1");
20 
21 //创建新节点下的子节点
22 TiXmlElement *ageElement = new TiXmlElement("WaterMark");
23 ageElement->SetAttribute("copies""2");
24 ageElement->SetAttribute("type""1");
25 x1->LinkEndChild(nameElement);
26 x1->LinkEndChild(ageElement);
27 
28         //  TiXmlText *nameContent = new TiXmlText("aaa");
29         //     TiXmlText *ageContent = new TiXmlText("12");
30        //  nameElement->LinkEndChild(nameContent);
31        //  ageElement->LinkEndChild(ageContent);
32 
33 //保存xml文件
34  pXmlDoc->SaveFile(sXmlPath);

 

posted @ 2012-03-06 15:26 王海光 阅读(1750) | 评论 (0)编辑 收藏
来自:http://blog.csdn.net/s3c44b0x/article/details/5469269

方法一:在对话框的属性中,在more   style中有一项是System   model,选上它,即可!
方法二:OnInitDialog里加入SetWindowPos(&wndTopMost,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);

外部调用: m_dialog->SetWindowPos(&wndTopMost, 0, 0, 400, 400, SWP_SHOWWINDOW);

 

MFC弹出非模态对话框

新建对话框IDD_DIALOG_TEST

用向导新建相应的类CTestDialog

在文件头#include “TestDialog.h”

 
CTestDialog *pTestDlg = new CTestDialog();
pTestDlg->Create(IDD_DIALOG_TEST, this);
pTestDlg->ShowWindow(SW_SHOW);

 

窗口保持在最前方

SetWindowPos(&wndTopMost,110,108,811,491,SWP_SHOWWINDOW);//这是标准位置

销毁窗口

pTestDlg->Destroy Windows;

delet pTestDlg;

posted @ 2012-03-02 10:08 王海光 阅读(5175) | 评论 (0)编辑 收藏

大家在启动服务器时,有时正常启动有时又启动不了是怎么回事呢??那为什么关掉迅雷等软件就又好了呢??现在就来给大家讲解一下,

如何查询端口被占用的程序 - kakis - Kakis

转自:http://yinkai210.blog.163.com/blog/static/287483452009050256466/

这些端口如果被其他程序占用就不能正常启动,比如有时启动时会提示WEB启动失败,其实就是80端口被占用了,而迅雷等下载软件恰恰就是占用了80端口,关掉就行了。但有时迅雷等都没有开也启动不了,那就是别的东西占用了,那怎么办呢?我来叫你查看端口并关掉的方法。
1.在开始--运行   里面输入cmd点回车,会出现运行窗口。
2.在提示符后输入netstat -ano回车,找到tcp 80端口对应的pid,比如1484.
3.ctrl+alt+del打开任务管理器,选进程,这里有很多正在运行的程序怎么找?别急点上面的   查看--选择列--在PID(进程标示符)前面打钩。好了,下面的进程前面都有了PID号码。这时上一步找到的PID就有用了,找到1484,比如PEER.EXE什么的,结束进程吧。这时再开服务器,看WEB可以启动了!

如上面的不清楚还有简明的:

假如我们需要确定谁占用了我们的80端口

1、Windows平台
在windows命令行窗口下执行:
C:\>netstat -aon|findstr "80"
TCP     127.0.0.1:80         0.0.0.0:0               LISTENING       2448
看到了吗,端口被进程号为2448的进程占用,继续执行下面命令:
C:\>tasklist|findstr "2448"
thread.exe                     2016 Console                 0     16,064 K
很清楚吧,thread占用了你的端口,Kill it
如果第二步查不到,那就开任务管理器,看哪个进程是2448,然后杀之即可。

如果需要查看其他端口。把 80 改掉即可

Linux查看端口使用状态、关闭端口方法
转自:http://blog.csdn.net/wudiyi815/article/details/7473097
前提:首先你必须知道,端口不是独立存在的,它是依附于进程的。某个进程开启,那么它对应的端口就开启了,进程关闭,则该端口也就关闭了。下次若某个进程再次开启,则相应的端口也再次开启。而不要纯粹的理解为关闭掉某个端口,不过可以禁用某个端口。

1. 可以通过"netstat -anp" 来查看哪些端口被打开。
(注:加参数'-n'会将应用程序转为端口显示,即数字格式的地址,如:nfs->2049, ftp->21,因此可以开启两个终端,一一对应一下程序所对应的端口号)
2. 然后可以通过"lsof -i:$PORT"查看应用该端口的程序($PORT指对应的端口号)。或者你也可以查看文件/etc/services,从里面可以找出端口所对应的服务。
(注:有些端口通过netstat查不出来,更可靠的方法是"sudo nmap -sT -O localhost")
3. 若要关闭某个端口,则可以:
1)通过iptables工具将该端口禁掉,如:
 "sudo iptables -A INPUT -p tcp --dport $PORT -j DROP"
 "sudo iptables -A OUTPUT -p tcp --dport $PORT -j DROP"    
2)或者关掉对应的应用程序,则端口就自然关闭了,如:
 "kill -9 PID" (PID:进程号)
  如:    通过"netstat -anp | grep ssh"
  有显示:    tcp 0 127.0.0.1:2121 0.0.0.0:* LISTEN 7546/ssh
  则:    "kill -9 7546"

(可通过"chkconfig"查看系统服务的开启状态)

posted @ 2012-02-22 17:06 王海光 阅读(964) | 评论 (0)编辑 收藏
(一) 原理
  1、最小化的原理:首先要将窗口隐藏,然后在右下角绘制图标。
  2、恢复的原理:将窗口显示,再将托盘中的图片删除。

(二)程序实现
  1、自定义消息WM_SHOWTASK: 

1 #define WM_SHOWTASK (WM_USER +1)

 

   2、在MFC的 

1 ::OnSysCommand(UINT nID, LPARAM lParam) 函数体中增加一个命令响应
2 if(nID==SC_MINIMIZE)
3 ToTray(); //最小化到托盘的函数

   3、在消息映射中添加  

1 ON_MESSAGE(WM_SHOWTASK,OnShowTask); //其中WM_SHOWTASK是消息名,
2 OnShowTask是自己定义的消息响应函数,后面有说明。

(三)具体函数内容
1、最小化到托盘函数 

 1 void CMyDlg::ToTray()
 2 {
 3   NOTIFYICONDATA nid;
 4   nid.cbSize=(DWORD)sizeof(NOTIFYICONDATA);
 5   nid.hWnd=this->m_hWnd;
 6   nid.uID=IDR_MAINFRAME;
 7   nid.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP ;
 8   nid.uCallbackMessage=WM_SHOWTASK;//自定义的消息名称
 9   nid.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME));
10   strcpy(nid.szTip,"程序名称"); //信息提示条
11   Shell_NotifyIcon(NIM_ADD,&nid); //在托盘区添加图标
12   ShowWindow(SW_HIDE); //隐藏主窗口
13 }

 

2、恢复界面函数

 1 在头文件中定义消息响应函数
 2 afx_msg LRESULT OnShowTask(WPARAM wParam,LPARAM lParam) ;
 3 //wParam接收的是图标的ID,而lParam接收的是鼠标的行为
 4 LRESULT CMyDlg::OnShowTask(WPARAM wParam,LPARAM lParam)
 5 {
 6   if(wParam!=IDR_MAINFRAME)
 7   return 1;
 8   switch(lParam)
 9   {
10       case WM_RBUTTONUP://右键起来时弹出快捷菜单,这里只有一个“关闭”
11   {
12       LPPOINT lpoint=new tagPOINT;
13       ::GetCursorPos(lpoint);//得到鼠标位置
14       CMenu menu;
15       menu.CreatePopupMenu();//声明一个弹出式菜单
16       menu.AppendMenu(MF_STRING,WM_DESTROY,"关闭"); //增加菜单项“关闭”,点击则发送消息  WM_DESTROY给主窗口(已隐藏),将程序结束。
17       menu.TrackPopupMenu(TPM_LEFTALIGN,lpoint->x,lpoint->y,this); //确定弹出式菜单的位置
18       HMENU hmenu=menu.Detach();
19       menu.DestroyMenu(); //资源回收
20       delete lpoint;
21   } break;
22   case WM_LBUTTONDBLCLK: //双击左键的处理
23   {
24       this->ShowWindow(SW_SHOW);//简单的显示主窗口完事儿
25       DeleteTray();
26   } break;
27   defaultbreak;
28   }
29       return 0;
30   }

3、删除托盘图标函数 

 1 void CMyDlg::DeleteTray()
 2 {
 3   NOTIFYICONDATA nid;
 4   nid.cbSize=(DWORD)sizeof(NOTIFYICONDATA);
 5   nid.hWnd=this->m_hWnd;
 6   nid.uID=IDR_MAINFRAME;
 7   nid.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP ;
 8   nid.uCallbackMessage=WM_SHOWTASK; //自定义的消息名称
 9   nid.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME));
10   strcpy(nid.szTip,"程序名称"); //信息提示条为“计划任务提醒”
11   Shell_NotifyIcon(NIM_DELETE,&nid); //在托盘区删除图标
12 }

 

posted @ 2011-10-22 13:14 王海光 阅读(1106) | 评论 (0)编辑 收藏
仅列出标题
共27页: First 19 20 21 22 23 24 25 26 27