项目编程中期的一些问题总结

1、图像动态增强

分块增强的时候窗口宽度超过数据的宽度,而均匀化的时候是除以整个窗口面积。导致最后处理完后图像偏白。

解决办法:当窗口宽度超过数据宽度时,使用数据的宽度当作窗口宽度。而窗口宽度小于数据宽度时,使用窗口宽度进行分块处理。运行结果正常。

2、窗口背景图问题

打开很多新文档窗口后,在有背景的时候拖拽有明显延迟。缩放的时候背景图失真。

解决办法:重新写了一个设置背景图片的DEMO。

3、BCG界面库使用问题

解决办法:框架使用BCG,里面有一些控件保留OLE类型。

4、调色棒问题

颜色不是渐变显示

解决办法:用GDI+的渐变画笔绘制(在OnDrawItem与OnPaint两种实现方法)

5、64为平台编程与32位平台编程区别

数据类型特别是int相关的类型在不同位数机器的平台下长度不同。C99标准并不规定具体数据类型的长度大小,只规定级别。作下比较:


                                                                                                                                32位平台                                64位平台

char 1个字节8位                  char 1个字节

  short 2个字节16位                 short 2个字节

   int 4个字节32位                     int 4个字节

              long 4个字节                long 8个字节(区别)

     long long 8个字节             long long 8个字节

                  指针 4个字节            指针 8个字节(区别)


为了保证平台的通用性,程序中尽量不要使用long数据库型。可以使用固定大小的数据类型宏定义,这些宏定义需要引用stdint.h头文件:

typedef signed char int8_t

typedef short int int16_t;

typedef int int32_t;

# if __WORDSIZE == 64

typedef long int int64_t;

# else

__extension__

typedef long long int int64_t;

#endif

       使用int时也可以使用intptr_t来保证平台的通用性,它在不同的平台上编译时长度不同,但都是标准的平台字长,比如64位机器它的长度就是8字节,32位机器它的长度是4字节,使用它可以安全地进行整数与指针的转换运算,也就是说当需要将指针作为整数运算时,将它转换成intptr_t进行运算才是安全的。intptr_t需要引用stddef.h头文件,它的定义如下:

#if __WORDSIZE == 64

typedef long int intptr_t;

#else

typedef int intptr_t;

#endif

编程中要尽量使用sizeof来计算数据类型的大小

以上类型定义都有相应的无符号类型。

        使用ssize_t和size_t

它们分别是unsigned和signed size of computer word size。它们也是表示计算机的字长,在32位机器上是int型,在64位机器上long型。使用它们对于增加平台的通用性有很大好处,从某种意义上来说它们等同于intptr_t和uintptr_t。使用它们也需要引用stddef.h头文件。


一个32位的程序,在64位机上运行,至多调用4G的内存。两个编译平台——Win32 和 x64。

最常见的判断有两种——

1.判断程序位数:当前程序被编译到了哪个平台。

2.判操作系统位数:当前程序是运行在32位的操作系统上,还是64位的操作系统。

将 C++ 应用程序设置为面向 64 位平台

   1.打开要配置为面向 64 位平台的 C++ 项目。

   2.打开该项目的属性页。

     对于 .NET 项目,请确保在“<项目名> 属性页”对话框中选择“配置属性”节点或其子节点之一。

     否则,“配置管理器”按钮仍为禁用。

   3.单击“配置管理器”打开“配置管理器”对话框。

   4.单击“活动解决方案平台”列表,然后选择“<新建...>”选项以打开“新建解决方案平台”对话框。

   5.单击“键入或选择新平台”下拉箭头,然后选择一个 64 位平台。

     在“新建解决方案平台”对话框中,可以使用“从此处复制设置”选项将

     现有的项目设置复制到新的 64 位项目配置中。

   6.单击“确定”。在上一步中选择的平台将出现在“配置管理器”对话框中的“活动解决方案平台”下。

   7.在“配置管理器”对话框中单击“关闭”,然后在“<项目名> 属性页”对话框中单击“确定”。

将Win32项目设置复制到 64 位项目配置中

将项目设置为面向 64 位平台时,如果“新建解决方案平台”对话框打开,则单击“从此处复制设置”下拉箭头,然后选择“Win32”。以下项目设置将在项目级得到自动更新:

 /MACHINE(指定目标平台)设置为 /MACHINE:IA64 或 /MACHINE:X64。

  “注册输出”被关闭。

  “目标环境”设置为 /envx64 或 /envia64。

    清除“验证参数”,将其重置为默认值。

    如果在 Win32 项目配置中将“调试信息格式”设置为/ZI,则在64位项目配置中将其设置为/Zi。

   WIN32 值被替换为 /D(预处理器定义)的 WIN64。

    如果在文件级重写这些项目属性,那么这些属性都不会改变

 6、MAC地址问题 

        MAC(Medium/Media Access Control)地址,用来表示互联网上每一个站点的标识符,采用十六进制数表示,共六个字节(48位)。其中,前三个字节是由IEEE的注册管理机构RA负责给不同厂家分配的代码(高位24位),也称为“编制上唯一的标识符”(Organizationally Unique Identifier),后三个字节(低位24位)由各厂家自行指派给生产的适配器接口,称为扩展标识符(唯一性)。一个地址块可以生成2^24个不同的地址。

00-23-5A-15-99-42

7、位运算为题

由于位运算直接对内存数据进行操作,不需要转成十进制,因此处理速度非常快。

位运算符C语言提供了六种位运算符:

  & 按位与

  | 按位或

  ^ 按位异或

  ~ 取反

  << 左移

  >> 右移

1. 按位与运算 按位与运算符"&"是双目运算符。其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位均为1时,结果位才为1 ,否则为0。参与运算的数以补码方式出现。

  例如:9&5可写算式如下: 00001001 (9的二进制补码)&00000101 (5的二进制补码) 00000001 (1的二进制补码)可见9&5=1。

  按位与运算通常用来对某些位清0或保留某些位。例如把a 的高八位清 0 ,保留低八位, 可作 a&255 运算 ( 255 的二进制数为0000000011111111)。

应用:

a. 清零特定位 (mask中特定位置0,其它位为1,s=s&mask)

b. 取某数中指定位 (mask中特定位置1,其它位为0,s=s&mask)

 

2. 按位或运算 按位或运算符“|”是双目运算符。其功能是参与运算的两数各对应的二进位相或。只要对应的二个二进位有一个为1时,结果位就为1。参与运算的两个数均以补码出现。

  例如:9|5可写算式如下:

00001001|00000101

00001101 (十进制为13)可见9|5=13

应用:

常用来将源操作数某些位置1,其它位不变。 (mask中特定位置1,其它位为0 s=s|mask)

3. 按位异或运算按位异或运算符“^”是双目运算符。其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。参与运算数仍以补码出现,例如9^5可写成算式如下:

00001001^00000101 00001100 (十进制为12)

应用:

a. 使特定位的值取反 (mask中特定位置1,其它位为0s=s^mask)

b. 不引入第三变量,交换两个变量的值 (设 a=a1,b=b1)

目标 操 作 操作后状态

a=a1^b1 a=a^b a=a1^b1,b=b1

b=a1^b1^b1 b=a^b a=a1^b1,b=a1

a=b1^a1^a1 a=a^b a=b1,b=a1

4. 求反运算求反运算符~为单目运算符,具有右结合性。其功能是对参与运算的数的各二进位按位求反。例如~9的运算为: ~(0000000000001001)结果为:1111111111110110

5. 左移运算左移运算符“<<”是双目运算符。其功能把“<< ”左边的运算数的各二进位全部左移若干位,由“<<”右边的数指定移动的位数,高位丢弃,低位补0。其值相当于乘2。例如: a<<4 指把a的各二进位向左移动4位。如a=00000011(十进制3),左移4位后为00110000(十进制48)。

6. 右移运算 右移运算符“>>”是双目运算符。其功能是把“>>”左边的运算数的各二进位全部右移若干位,“>>”右边的数指定移动的位数。其值相当于除2。

例如:设 a=15,a>>2 表示把000001111右移为00000011(十进制3)。对于左边移出的空位,如果是正数则空位补0,若为负数,可能补0或补1,这取决于所用的计算机系统。。

 8、句柄问题

HANDLE CreateFile(
LPCTSTR
lpFileName, // 文件名
DWORD
dwDesiredAccess, // 访问方式
DWORD
dwShareMode, // 共享模式
LPSECURITY_ATTRIBUTES
lpSecurityAttributes, // 设为NULL
DWORD
dwCreationDisposition, /// 创建方式
DWORD
dwFlagsAndAttributes, // 属性
HANDLE
hTemplateFile
);

 

句柄是在windows编程中的一个概念,类型是HANDLE,这个其实不是一个类,HANDLE在windows其实只是一个类型定义,其内部的类型是数值类型(例如int),这个只是为了唯一标示一个对象/内核对象而已。

 

句柄是一个32位的整数,实际上是Windows在内存中维护的一个对象内存物理地址列表的整数索引。因为Windows的内存管理经常会将空闲对象的内存释放掉,当需要访问时再重新提交到物理内存,所以对象的物理地址是变化的,不允许程序直接通过物理地址来访问对象。程序将想访问的对象的句柄传递给系统,系统根据句柄检索自己维护的对象列表就能知道程序想访问的对象及物理地址了。

句柄是一种指向指针的指针。我们知道,所谓指针是一种内存地址。应用程序启动后,组成这个程序的各对象是驻留在内存的。如果简单地理解,似乎我们只要获知这个内存的首地址,那么就可以随时用这个地址访问对象。但是,Windows是一个以虚拟内存为基础的操作系统。在这种系统环境下,Windows内存管理器经常在内存中来回移动对象,以此来满足各种应用程序的内存需要。对象被移动意味着它的地址变化了。如果内存总是如此变化,我们该到哪里去找该对象呢?为了解决这个问题,Windows操作系统为各应用程序腾出一些内存地址,用来专门登记各应用对象在内存中的地址变化,而这个地址本身是不会变的。Windows内存管理器移动对象在内存中的位置后,把对象新的地址告知这个句柄地址来保存。这样我们只需要记住这个句柄地址就可以间接地知道对象具体在内存中的哪个位置。这个地址是在对象装载时由系统分配的,当系统卸载时又释放给系统。但是,必须注意的是,程序每次重新启动,系统不能保证分配给这个程序的句柄还是原来的那个句柄。而且绝大多数情况下的确不一样。假如我们把进入电影院看电影看成是一个应用程序的启动运行,那么系统给应用程序分配的句柄总是不一样,这和每次电影院售给我们的门票总是不同的座位是一样的道理。

句柄实际上是一种指向某种资源的指针,但与指针又有所不同:指针对应着一个数据在内存中的地址,得到了指针就可以自由地修改该数据。Windows并不希望一般程序修改其内部数据结构,因为这样太不安全。所以只是在调用API函数时利用这个句柄来说明要操作哪段内存。

在Windows环境中,句柄是用来标识项目的,这些项目包括:模块(module)、任务(task)、实例 (instance)、文件(file)、内存块(block of memory)、菜单(menu)、控制(control)、字体(font)、资源(resource),包括图标(icon),光标 (cursor),字符串(string)等、GDI对象(GDI object),包括位图(bitmap),画刷(brush),元文件(metafile),调色板(palette),画笔(pen),区域 (region),以及设备描述表(device context)。

HMODULE;

HINSTANCE;

HLOCAL;

HGLOBAL;

HDC;

HRGN;

HWND;

HMENU;

HACCEL;

HTASK;

 9、OCX控件问题

OCX文件,在视图里或对话框里,用右键选择类似"添加 ACTIVE CONTROL"的选项,即插入控件,然后再关联对应的变量和生成这个控件的消息函数就可以。

如果不方便用这种方法,可以生成一个对话框程序,然后你在资源视图里会显示生成的对话框,再右键选择类似"添加 ACTIVITE CONTROL"的选项,然后再关联这个控件的变量,这时就会生成这个控件的类文件,这时你就可以把生成的类文件考到你的工程里,至于这个控件的消息函数的映射语法,也可以在对话框里生成,然后把相应的代码考到工程里。


在WindowsXP系统中,VC6可以通过工程-》添加到工程-》添加OCX,

在Windows7系统中,可以看到OCX,但是添加的时候提示 “不支持此接口”;

 

解决方法:

1:在对话框上直接右键 “InsertActiveX Control”,这个时候类视图中还没有所添加OCX的类文件,

2:然后选中所添加的OCX,用向导添加变量,这样VC6会为程序添加这个OCX对应的类文件了;

3:删除刚添加的OCX关联的变量也没问题了;

在XP系统VC6中,如果ocx添加新的接口了,重新导入ocx就可以了;

在win7系统VC6中,重新注册好添加接口的ocx,然后新建一个工程导入,然后将生成的.h 和 .cpp 复制到原工程中。


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值