Code

来源:互联网 发布:小米5没有网络 编辑:程序博客网 时间:2024/06/05 20:24

续行符 /

 

typedef struct _PROPSHEETPAGEA_V2
{
    PROPSHEETPAGEA_V1_FIELDS

    LPCSTR           pszHeaderTitle;    // this is displayed in the header
    LPCSTR           pszHeaderSubTitle; //
} PROPSHEETPAGEA_V2, *LPPROPSHEETPAGEA_V2;

 

#define PROPSHEETPAGEW_V1_FIELDS   /
    DWORD           dwSize;        /
    DWORD           dwFlags;       /
    HINSTANCE       hInstance;     /
    union                          /
    {                              /
        LPCWSTR     pszTemplate;   /
        PROPSHEETPAGE_RESOURCE pResource; /
    } DUMMYUNIONNAME;              /
... ...
    UINT             *pcRefParent; /

 


 

BOOL UpdateResource(HANDLE hUpdate,LPCTSTR lPTyPe,LPCTSTR IPName,WORD wLanguage,LPVOID lgData,DWORD cbData);

该函数增加,删除,或替代某可执行文件中的资源。

 

 


 

FindResourceEx
  该函数确定指定模块中指定类型、名称及语言的资源所在位置。
  函数原型:HRSRC FindResourceEx(HXODULE hModule,LPCTSTR lpType,LPCTSTR lpName,WORD wLanguage);
  参数:
  hModule:处理包含资源的可执行文件的模块。如果参数值为NULL,则函数搜索曾经创建的最近过程的模块。
  lpType:指向以NULL为结束符的字符串,它指定了被列举出的资源类型名称。作为标准类型,这个参数取值同EnumResLangProc/lpType。
  lpName:指向说明资源文件名称并以NULL为结束符的字符串。
  WLanguage:指明语言资源。若此参数为MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),则为了指定零一种语言,可以使用宏创建这个参数。更多的信息请参见MAKELANGID。

 

1.      FindResource用来在一个指定的模块中定位所指定的资源:

2.             HRSRC FindResource(

3.             HMODULE hModule,                //包含所需资源的模块句柄,如果是程序本身,可以置为NULL

4.             LPCTSTR lpName,         //可以是资源名称或资源ID

5.             LPCTSTR lpType          //资源类型,在这里也就是我们自己指定的资源类型

6.             );     

7.      LoadResource用来将所指定的资源加载到内存当中;

8.             HGLOBAL LoadResource(

9.             HMODULE hModule,                //模块句柄,同上

10.          HRSRC hResInfo          //需要加载的资源句柄,这里也就是FindResource的返回值

11.          );             

12.   LockResource用来锁定内存中的资源数据块,它的返回值也就是我们要使用的指向资源数据的内存指针;

13.          LPVOID LockResource(

14.          HGLOBAL hResData                //指向内存中要锁定的资源数据块,这里也就是LoadResource的返回值

15.          );  

 

 

对话框框创建例程 CreateDialog(), CreateDialogParam(), CreateDialogIndirect(), CreateDialogIndirectParam(), DialogBox(), DialogBoxParam(), DialogBoxIndirect(), and DialogBoxIndirectParam()

 

DialogBoxIndirect 

int DialogBoxIndirect(
  HINSTANCE hInstance,
  LPDLGTEMPLATE lpTemplate,
  HWND hWndParent,
  DLGPROC lpDialogFunc
);

 

DialogBox

该宏根据对话框模板资源创建一个模态的对话框。DialogBOX函数直到指定的回调函数通过调用EndDialog函数中止模态的对话框才能返回控制。该宏使用DialogBoxParam函数。
  函数原型:int DialogBox(HINSTANCE hlnstance,LPCTSTRIpTemplate,HWND hWndParent,DLGPROC IpDialogFunc);
  参数:
  hlnstance:标识一个模块的事例该模块的可执行文件含有对话框模板。
  IpTemplate:标识对话框模板。此参数可以是指向一个以NULL结尾的字符串的指针,该字符串指定对话框模板名,或是指定对话框模板的资源标识符中的一个整型值。如果此参数指定了一个资源标识符则它的高位字一定为零,且低位字一定含有标识符。一定用MAKEINTRESOURDE宏指令创建此值。
  hWndParent:指定拥有对话框的窗口。
  IpDialogFunc:指向对话框过程的指针。有关更详细的关于对话框过程的信息,请参见DialogProc。
  返回值:如果函数调用成功,则返回值为在对函数EndDialog的调用中的nResult参数.该函数用于中止对话框。如果函数调用失败,则返回值为-1。若想获得更多的错误信息,请调用GetLastError函数。
  备注:DialOgBox宏用CreateWindowEx函数创建对话框。DialogBox函数然后把一个WM_INITDIALOG消息(和一个WM-SETFONT消息,如果模板指定DS_SETFONT类型)传递到对话框过程。不管模板是否指定WS_VISIBLE类型,函数显示对话框,并且使拥有该对话框的窗口(也称属主窗口)失效,且为对话框启动它本身的消息循环来检索和传递消息。
  当对话框应用程序调用EndDialog函数时,DialogBox函数清除对话框户止消息循环,使属主窗口生效(如果以前有效),且返回函数EndDialog调用中的nReSUlt参数。

 


 

 C(和C++)中的宏(Macro)属于编译器预处理的范畴,属于编译期概念(而非运行期概念)。下面对常遇到的宏的使用问题做了简单总结。

1)#    把参数产开并转化成字符串即用""引起来。里面的空格分割全部改为一个,并且会自动添加转义字符'/'
2)## 把前后两个东西连起来形成新的标示符。
3)#@和#类似,只不过是用''单引号引起来。

 

关于###

C语言的宏中,#的功能是将其后面的宏参数进行字符串化操作(Stringfication),简单说就是在对它所引用的宏变量通过替换后在其左右各加上一个双引号。比如下面代码中的宏:

#define WARN_IF(EXP)    /

    do{ if (EXP)    /

            fprintf(stderr, "Warning: " #EXP "/n"); }   /

    while(0)

那么实际使用中会出现下面所示的替换过程:

WARN_IF (divider == 0);

 

       被替换为

 

do {

    if (divider == 0)

                       fprintf(stderr, "Warning" "divider == 0" "/n");

} while(0);

这样每次divider(除数)为0的时候便会在标准错误流上输出一个提示信息。

 

##被称为连接符(concatenator),用来将两个Token连接为一个Token。注意这里连接的对象是Token就行,而不一定是宏的变量。比如你要做一个菜单项命令名和函数指针组成的结构体的数组,并且希望在函数名和菜单项命令名之间有直观的、名字上的关系。那么下面的代码就非常实用:

struct command

{

       char * name;

       void (*function) (void);

};

 

#define COMMAND(NAME) { NAME, NAME ## _command }

 

// 然后你就用一些预先定义好的命令来方便的初始化一个command结构的数组了:

 

struct command commands[] = {

       COMMAND(quit),

       COMMAND(help),

       ...

}

COMMAND宏在这里充当一个代码生成器的作用,这样可以在一定程度上减少代码密度,间接地也可以减少不留心所造成的错误。我们还可以n##符号连接 n+1Token,这个特性也是#符号所不具备的。比如:

#define LINK_MULTIPLE(a,b,c,d) a##_##b##_##c##_##d

 

typedef struct _record_type LINK_MULTIPLE(name,company,position,salary);

// 这里这个语句将展开为:

//    typedef struct _record_type name_company_position_salary;

关于...的使用

...C宏中称为Variadic Macro,也就是变参宏。比如:

#define myprintf(templt,...) fprintf(stderr,templt,__VA_ARGS__)

 

       // 或者

 

#define myprintf(templt,args...) fprintf(stderr,templt,args)

第一个宏中由于没有对变参起名,我们用默认的宏__VA_ARGS__来替代它。第二个宏中,我们显式地命名变参为args,那么我们在宏定义中就可以用args来代指变参了。同C语言的stdcall一样,变参必须作为参数表的最有一项出现。当上面的宏中我们只能提供第一个参数templt时,C标准要求我们必须写成:

myprintf(templt,);

的形式。这时的替换过程为:

myprintf("Error!/n",);

 

       替换为:

      

fprintf(stderr,"Error!/n",);

这是一个语法错误,不能正常编译。这个问题一般有两个解决方法。首先,GNU CPP提供的解决方法允许上面的宏调用写成:

myprintf(templt);

而它将会被通过替换变成:

fprintf(stderr,"Error!/n",);

很明显,这里仍然会产生编译错误(非本例的某些情况下不会产生编译错误)。除了这种方式外,c99GNU CPP都支持下面的宏定义方式:

#define myprintf(templt, ...) fprintf(stderr,templt, ##__VAR_ARGS__)

这时,##这个连接符号充当的作用就是当__VAR_ARGS__为空的时候,消除前面的那个逗号。那么此时的翻译过程如下:

myprintf(templt);

 

       被转化为:

 

fprintf(stderr,templt);

这样如果templt合法,将不会产生编译错误。 这里列出了一些宏使用中容易出错的地方,以及合适的使用方式。

  


内存访问速度远不及CPU处理速度,为提高机器整体性能,在硬件上引入硬件高速缓存Cache,加速对内存的访问。另外在现代CPU中指令的执行并不一定严格按照顺序执行,没有相关性的指令可以乱序执行,以充分利用CPU的指令流水线,提高执行速度。以上是硬件级别的优化

再看软件一级的优化:一种是在编写代码时由程序员优化,另一种是由编译器进行优化。编译器优化常用的方法有:将内存变量缓存到寄存器;调整指令顺序充分利用CPU指令流水线,常见的是重新排序读写指令。

 

当给变量加上volatile关键字,除了表示这一变量可以被其他代理改变值,也明确说明编译器不能为此变量进行上面那种方式的优化:每次调用这一变量,都从变量的地址中获取值,而不是寄存器(此变量使用的硬件内存地址是与其他并行运行的程序共享数据的,因此不管是程序自身改变变量值,还是其他代理改变变量值,都是改变内存地址中的数据)。

 

restrict关键字只能用来修饰指针,表示被定义的指针是访问指针中数据的唯一途径。这一目的是告诉编译器可以进行一些优化。

原创粉丝点击