我爱builder

C++Builder 程序员博客

Archive for 01月, 2009

本来想自己解决,但是始终找不到解决方法,希望热心的人能给个帮助
我想实现的就是鼠标移动时,横坐标对应的series1的曲线值(chart1中就一个曲线series1)

目前有的情况是
1,只能找出鼠标处的横纵坐标(不是我想要的结果)

2,只可以显示鼠标移到曲线上时的曲线的值,往上或往下移鼠标都不会显示值
(getcursevalueindex,即获取鼠标处有值情况下的索引值,然后根据索引求得曲线值)
但是我想实现的是鼠标任意位置处时横坐标对应的曲线值,而不是鼠标仅仅在曲线上才能显示

3,当曲线连续时,可以人为的计算索引值,但是目前我的曲线不连续,可能今天的某一个小时有2个点,然后一下跳到明天有2个点(无规律)

求各位大虾帮帮忙,小弟感激不尽

谢谢constantine
bcb带的Examples我看了,没有符合我要求的,可能是teechart开发的时候没有考虑到这种需求吧

请大家再帮帮忙吧,谢谢了

该回复于2008-07-10 02:51:36被版主删除

该回复于2008-07-19 16:14:20被版主删除

遇到了相似的问题,我现在需要根据鼠标的位置,找出曲线的横纵座标值。

现在的问题是,只有鼠标在曲线上时才可以找到

但是要求是鼠标任意位置处时横坐标对应的曲线值

不过我的曲线是连续的

你只能同时显示多个坐标,对应series

  • Filed under: C++ Builder
  • 代码如下:

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    //连接WORD
      WordApplication1->Disconnect();
      WordApplication1->Connect();
    }

    void __fastcall TForm1::WordApplication1DocumentBeforePrint(
          TObject *Sender, WordDocument *Doc, VARIANT_BOOL *Cancel)
    {
    //WordApplication1->OnDocumentBeforePrint 事件
      ShowMessage("打印");
    }

    问题: 当点击WORD上的打印按钮时会出现莫名其妙的地址错误。 IDE为c++ builder6.0

    恳请各位C++高手前来指导!

    可以确定不是WORD的问题。 因为我用DELPHI 翻译过去的代码没有问题

    打印机设置看哈

    设置了虚拟打印机,也试过直接连接真实打印机了。相当郁闷!! 不知你们有没试过,我同事试了也是一样的问题。

    人气低落得让人伤心啊。55555555。。。。。。。。。。。。。。。。。。。。。。。。

  • Filed under: C++ Builder
  • 在一幅bmp图像上通过鼠标选定一块矩形区域,然后点击按钮,将选定的矩形区域另存为另外的bmp图像,整个操作过程都没有问题,问题就是另存以后的图像数据与原来位图上那块区域的图像数据有点对不上,好像是bcb在操作过程中对图像作了处理。
    比如原来的十六进制数据可能是73 74 75 72 73
    另存以后的十六进制数据变成了74 74 74 74 74
    好像被求了一个平均,因为数据差别不大肉眼很难看出来,直接察看数据文件才发现
    麻烦各位高手指点一下该怎样设置才能让bcb不要修改我的图像数据直接拷贝保存出来?谢谢!
    部分相关代码如下,我手动敲得,可能有大小写之类的错误,见谅:

    C/C++ code
    // 前提 // ImageCreate位于ScrollBox中,待截取的图片位于ImageCreate中 // 通过鼠标拖拽在ImageCreate中选定要截取的范围,为了避免拖拽时闪烁ScrollBox开了双缓冲 // ImageCreate->Canvas的画笔设置为宽度1,虚线psDash和非异或pmNotXor // 鼠标选定的矩形框的4个顶点坐标顺时针保存在全局变量X_start,X_end,Y_start,Y_end中 // 存放截取下来的位图图片 TPicture *picLoad = new(TPicture); // 根据选定的图形大小设置位图大小 picLoad->Bitmap->Width = X_end - X_start; picLoad->Bitmap->Height = Y_end - Y_start; // 重绘矩形,消除虚线框,避免保存图片时连虚线框一起保存下来 ImageCreate->Canvas->Rectangle(X_start,Y_start,X_end,Y_end); // 从ImageCreate中拷贝指定大小的图片到picLoad中 picLoad->Bitmap->Canvas->CopyRect( Rect(0,0,picLoad->Bitmap->Width,picLoad->Bitmap->Height), ImageCreate->Canvas, Rect(X_start,Y_start,X_end,Y_end)); // 重绘矩形,显示虚线框 ImageCreate->Canvas->Rectangle(X_start,Y_start,X_end,Y_end); // 另存截取下来的图片 picLoad->Bitmap->SaveToFile(SavePictureDialog->FileName);

    CopyMode = cmSrcCopy;

    试过了
    ImageCreate->Canvas和picLoad->Bitmap->Canvas的CopyMode都设置成了cmSrcCopy
    还是不行

    另外还用BitBlt函数试了一下
    dest和src的dc传的ImageCreate->Canvas和picLoad->Bitmap->Canvas的handle进去
    也不行

    C/C++ code
    picLoad->Bitmap->PixelFormat = ImageCreate->Picture->Bitmap->PixelFormat;

    另外,这样的处理为什么不直接用Graphics::TBitmap呢?而要在外面套一层TPicture?

    C/C++ code
    picLoad->Bitmap->PixelFormat = ImageCreate->Picture->Bitmap->PixelFormat;

    试过,也不行,图像还是发生变化了

    另外,这样的处理为什么不直接用Graphics::TBitmap呢?而要在外面套一层TPicture?当时没多想,功能上需要先打开图片再从中截取一部分另存
    所以用了Picture来加载图片,并拷贝到ImageCreate中,
    然后在ImageCreate中操作过后再通过picLoad去另存。
    要不我去试试换成TBitmap看看

    剪切的时候,也就是你鼠标拖动矩形的时候,分割出来的图像,长和宽是分别少一个像素的。
    你把少了像素的图像要另存到另一个标准像素的画板上,像素本来就不能完全符合,加上你使用伸缩,导致图像略有影响。

    楼上再算算

    剪切的时候,也就是你鼠标拖动矩形的时候,分割出来的图像,长和宽是分别少一个像素的。
    你把少了像素的图像要另存到另一个标准像素的画板上,像素本来就不能完全符合,加上你使用伸缩,导致图像略有影响。

    跟大小无关,我也没有进行缩放

    知道问题大概出在哪里了,但还是不知道咋解决:

    C/C++ code
    // 打开并读取.bmp位图文件 picLoad->LoadFromFile(); // 拷贝位图文件到ImageCreate中,拷贝后ImageCreate能够正确地显示该图形 ImageCreate->Canvas->CopyRect( Rect(0,0,picLoad->Width,picLoad->Height), picLoad->Bitmap->Canvas, Rect(0,0,picLoad->Width,picLoad->Height)); // 为了测试将图片再次拷回picLoad中并重新拷贝到ImageCreate中,然后图片数据就变了 picLoad->Bitmap->Canvas->CopyRect( Rect(0,0,picLoad->Width,picLoad->Height), picLoad->Bitmap->Canvas, Rect(0,0,picLoad->Width,picLoad->Height)); ImageCreate->Canvas->CopyRect( Rect(0,0,picLoad->Width,picLoad->Height), picLoad->Bitmap->Canvas, Rect(0,0,picLoad->Width,picLoad->Height));

    可能是我拷贝到picLoad的Bitmap中导致图像数据发生改变
    可是只有Bitmap下才有Canvas,我该怎么办??

    picLoad->Bitmap->Canvas->CopyRect(
            Rect(0,0,picLoad->Width,picLoad->Height),
            picLoad->Bitmap->Canvas,
            Rect(0,0,picLoad->Width,picLoad->Height));

    这句有什么用?

    把 TPictrue 改成 TBitmap 会怎么样?

    不好意思,打错了,应该是:

    C/C++ code
    picLoad->Bitmap->Canvas->CopyRect( Rect(0,0,picLoad->Width,picLoad->Height), ImageCreate->Canvas, Rect(0,0,picLoad->Width,picLoad->Height));

    就是最开始用Picture读取图像,拷贝到Image中显示,都是对的,很正常
    当我再次将图像从Image中拷贝到Picture中,再拷回到Image中显示,图像的数据就不对了
    至于改成TBitmap我现在去试试~

    支持 shadowstar !
    把 TPictrue 改成 TBitmap 会怎么样?

    试过了,会失真

    测试时发现一些状况
    要打开的位图文件属性中的位深度是8
    通过TPicture->LoadFromFile读入再SaveToFile后位深度还是8,不会失真
    拷贝到Image->Canvas中再SaveToFile后位深度变成了32,失真较少
    拷贝到TBitmap->Canvas中再SaveToFile后位深度还是8,但会失真

    说到底,楼主的程序是在TBitmap和TImage之间传输图像数据,也就是说数据传输过程中必须要转换。

    楼主说位图深度8,那么就一定会出问题了!
    如果改成24或者32也许不会有问题,这个要试过才知道。

    保证不会发生改变的办法就是TImage只用来显示,数据传输都用TBitmap。

    位图深度是不能改的,这个图片之后要做图像匹配用,改了数据变化就大了,这点试过了

    前台通过TImage显示,拖拽鼠标确定出需要截取的图片的位置和大小
    后台则是在TBitmap中截取指定的图片,并保持位图深度8不变,图片不能失真

    查了一下TBitmap没有找到相关的方法可以裁剪图片的,有啥招没?

    建议你使用ImageCreate->Picture->Bitmap,并在初始化时设置:
    ImageCreate->Picture->Bitmap->PixelFormat = picLoad->Bitmap->PixelFormat;
    绘制可以在ImageCreate->Picture->Bitmap->Canvas上进行,否则系统可能会使用最接近的颜色进行处理。

    给你一个例子:(测试通过)

    C/C++ code
    //你可以手动自己设置,或者在程序初始化… //Shape1 Style ->bsClear 透明 //Shape1 Width->120, Height->160; //DBImage1 Width->153, Height->275; //image1 Width->233, Height->275; void __fastcall TForm1::Image1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { Shape1->Visible = true ; Shape1->Left = X+ Image1->Left; Shape1->Top = Y + Image1->Top; } //————————————————————————— void __fastcall TForm1::Shape1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { POINT MousePos; GetCursorPos(&MousePos); //相对于左面的位置 TRect rc,dc ; //创建巨型结构变量,rc源,dc 目标 rc=Rect(MousePos.x,MousePos.y,MousePos.x+120,MousePos.y+160); dc=Rect(0,0,120,160); TCanvas * myCanvas = new TCanvas(); myCanvas->Handle =GetDC(0); //获取左面窗口的设备句柄,0 指左面 //创建TBitmap类的对象–临时位图 Graphics::TBitmap * myBitmap= new Graphics::TBitmap(); myBitmap->Height = 160; myBitmap->Width=120; myBitmap->Canvas->CopyRect(dc,myCanvas,rc);//屏幕快复制到临时位图 DBImage1->Picture->Assign(myBitmap); //将临时位图分配致DBImage1对象 } //————————————————————————— void __fastcall TForm1::Shape1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { Shape1->Visible = false ; } //————————————————————————— void __fastcall TForm1::Image1MouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { Shape1->Visible = false ; } //————————————————————————— void __fastcall TForm1::FormCreate(TObject *Sender) { Shape1->Visible = false ; }

    TO ddeng:
    建议你使用ImageCreate->Picture->Bitmap,并在初始化时设置:
    ImageCreate->Picture->Bitmap->PixelFormat = picLoad->Bitmap->PixelFormat;
    绘制可以在ImageCreate->Picture->Bitmap->Canvas上进行,否则系统可能会使用最接近的颜色进行处理。

    刚刚看到,谢谢你的热心,我去试试,不过不抱太大希望,已经快被折腾死了

    TO zhouzhangkui:
    不好意思,没太看懂你的代码是啥意思
    是不是想通过shape来将Image1中的位图拷贝到TBitmap中,然后再assign给DBImage1对吗?
    我这边的问题是
    本来是8位(256色)的位图文件
    通过TPicture组件LoadFromFile,再拷贝到ImageCreate中时,就已经变成了24位的位图文件
    就是说只要我想通过Image显示图片,图片就变成了24位的,应该有地方可以设置可是我找不到
    后面不管我用什么操作去截取矩形区域,图像数据都已经被改变了

    实在无解的话有个不是办法的办法:
    前台通过界面确定出需要截取的矩形的位置和大小
    后台再去读源位图文件并解析,将位图数据读到一个二维数组中
    然后根据前台的数据信息取出其中对应矩形的部分数据,并添加位图头部信息另存
    实在不想这么干,觉得bcb肯定能够支持的,只是我不知道而已,继续求解

    引用 18 楼 helenhf 的回复:
    TO zhouzhangkui:
    不好意思,没太看懂你的代码是啥意思
    是不是想通过shape来将Image1中的位图拷贝到TBitmap中,然后再assign给DBImage1对吗?

    对,是这样的,我的已经测试成功,你可以试试看,
    你把我的按你的要求改改吧

    引用 16 楼 ddeng 的回复:
    建议你使用ImageCreate->Picture->Bitmap,并在初始化时设置:
    ImageCreate->Picture->Bitmap->PixelFormat = picLoad->Bitmap->PixelFormat;
    绘制可以在ImageCreate->Picture->Bitmap->Canvas上进行,否则系统可能会使用最接近的颜色进行处理。

    试过了,不行
    如果把picLoad->Bitmap->PixelFormat传给ImageCreate的话,显示的时候就已经失真了,虽然是8位深度
    如果不传,那么用ImageCreate->Picture->Bitmap另存出来的图片的位数就不对了,好像又变成32位的了

    引用 19 楼 zhouzhangkui 的回复:
    对,是这样的,我的已经测试成功,你可以试试看,
    你把我的按你的要求改改吧

    你用8位(256色)的位图试过了吗?成功的吗?
    我这边将图像拷贝到Image中显示的时候图像深度就已经变了
    后面不管怎样处理都不会对了

    如果是八位深度的Bitmap,你还需要处理调色板,否则显示可能不一样。

    引用 14 楼 shadowstar 的回复:
    说到底,楼主的程序是在TBitmap和TImage之间传输图像数据,也就是说数据传输过程中必须要转换。

    楼主说位图深度8,那么就一定会出问题了!
    如果改成24或者32也许不会有问题,这个要试过才知道。

    保证不会发生改变的办法就是TImage只用来显示,数据传输都用TBitmap。

    显示是显示,数据是数据,显示不要和数据混到一起!

    ImageCreate->Picture->Bitmap->Palette = picLoad->Bitmap->Palette;

    不好意思,我总是把你的ImageCreate和picLoad搞反了,呵呵。
    试试下面这样修改,如果还不行的话就直接用Graphics::TBitmap的Scan0指针进行直接内存复制吧。

    C/C++ code
    // 前提 // ImageCreate位于ScrollBox中,待截取的图片位于ImageCreate中 // 通过鼠标拖拽在ImageCreate中选定要截取的范围,为了避免拖拽时闪烁ScrollBox开了双缓冲 // ImageCreate->Canvas的画笔设置为宽度1,虚线psDash和非异或pmNotXor // 鼠标选定的矩形框的4个顶点坐标顺时针保存在全局变量X_start,X_end,Y_start,Y_end中 // 存放截取下来的位图图片 TPicture *picLoad = new(TPicture); //增加这两句 picLoad->Bitmap->PixelFormat = ImageCreate->Picture->Bitmap->PixelFormat; picLoad->Bitmap->Palette = ImageCreate->Picture->Bitmap->Palette; // 根据选定的图形大小设置位图大小 picLoad->Bitmap->Width = X_end - X_start; picLoad->Bitmap->Height = Y_end - Y_start; // 重绘矩形,消除虚线框,避免保存图片时连虚线框一起保存下来 ImageCreate->Canvas->Rectangle(X_start,Y_start,X_end,Y_end); // 从ImageCreate中拷贝指定大小的图片到picLoad中 picLoad->Bitmap->Canvas->CopyRect( Rect(0,0,picLoad->Bitmap->Width,picLoad->Bitmap->Height), ImageCreate->Picture->Bitmap->Canvas, Rect(X_start,Y_start,X_end,Y_end)); // 重绘矩形,显示虚线框 ImageCreate->Canvas->Rectangle(X_start,Y_start,X_end,Y_end); // 另存截取下来的图片 picLoad->Bitmap->SaveToFile(SavePictureDialog->FileName);

    引用 22 楼 shadowstar 的回复:
    显示是显示,数据是数据,显示不要和数据混到一起!

    好像明白你的意思
    可最后需要从图像数据中截取一块矩形区域出来
    只能用Canvas->CopyRect
    只要调用了这个函数,拷出来的图形要么失真,要么就不是8位深度的位图了

    [Quote=引用 24 楼 ddeng 的回复:]
    不好意思,我总是把你的ImageCreate和picLoad搞反了,呵呵。
    试试下面这样修改,如果还不行的话就直接用Graphics::TBitmap的Scan0指针进行直接内存复制吧。

    C/C++ code
    //增加这两句 picLoad->Bitmap->PixelFormat = ImageCreate->Picture->Bitmap->PixelFormat; picLoad->Bitmap->Palette = ImageCreate->Picture->Bitmap->Palette;

    [/Quote]
    代码在公司里,明天上班时再试试,没啥信心了
    实在没招只能直接解析位图文件了

    C/C++ code
    picLoad->Bitmap->PixelFormat = ImageCreate->Picture->Bitmap->PixelFormat; picLoad->Bitmap->Palette = ImageCreate->Picture->Bitmap->Palette;

    不行 @_@

    算了,我结贴了,提供最笨的一种方法:
    bmp位图数据依次包含位图文件头,位图信息和实际的图像数据
    位图信息又划分为位图信息头以及调色板,存储方式如下:

    1. 位图文件头
    2. 位图信息
        2.1 位图信息头
        2.2 调色板
    3. 实际的图象数据。

    数据结构如下:

    C/C++ code
    // 位图文件头,14个字节 typedef struct tagBITMAPFILEHEADER { /* bmfh */ WORD bfType; // 文件的类型,该值必需是0×4D42,也就是字符’BM’。 DWORD bfSize; // 文件的大小,以字节为单位 WORD bfReserved1; // 保留,必须设置为0 WORD bfReserved2; // 保留,必须设置为0 DWORD bfOffBits; // 文件头开始到实际的图象数据之间的字节的偏移量 } BITMAPFILEHEADER; // 位图信息 typedef struct tagBITMAPINFO { /* bmi */ BITMAPINFOHEADER bmiHeader; // 包含了有关位图的尺寸及位格式等信息 RGBQUAD bmiColors[x]; // 调色板,x由bfOffBits减去位图文件头14个字节和位图信息头40个字节确定 } BITMAPINFO; // 位图信息头 typedef struct tagBITMAPINFOHEADER { /* bmih */ DWORD biSize; // BITMAPINFOHEADER结构所需要的字数 LONG biWidth; // 图象的宽度,以象素为单位 LONG biHeight; // 图象的高度,以象素为单位 WORD biPlanes; // =1,不用管 WORD biBitCount; // 最多能表示的颜色数,单位:比特数/象素,其值为1、4、8、16、24、或32 // 1表示只有黑白两色 // 4表示最多16种颜色,每个象素4位 // 8表示最多256种颜色,每个象素8位 // 16/24/32较复杂,不解释,有兴趣的可以自己去查 DWORD biCompression; // 图象数据压缩的类型 // BI_RGB:没有压缩; // BI_RLE8:每个象素8比特的RLE压缩编码,压缩格式由2字节组成(重复象素计数和颜色索引); // BI_RLE4:每个象素4比特的RLE压缩编码,压缩格式由2字节组成 // BI_BITFIELDS:每个象素的比特由指定的掩码决定。 DWORD biSizeImage; // 图象的大小,以字节为单位。当用BI_RGB格式时,可为0 LONG biXPelsPerMeter; // 水平分辨率,单位:象素/米 LONG biYPelsPerMeter; // 垂直分辨率,单位:象素/米 DWORD biClrUsed; // 位图实际使用的调色板中的颜色索引数,0表示使用所有调色板项 DWORD biClrImportant; // 对图象显示有重要影响的颜色索引的数目,0表示都重要 } BITMAPINFOHEADER;

    调色板实际上是一组颜色值,采用RGBQUAD数组表示,数组中的每一项代表一个颜色
    例如红色表示为0xff0000
    这里的ff表示Red分量,中间两个00表示Green分量,后面两个00表示Blue分量

    剩下的位图数据实际上就是一个顺序存放的二维数组
    数组中每个元素的值就是调色板的索引,通过引用调色板来表示该位置的实际颜色
    bmp位图是按照从下往上,从左往右的方式逐行扫描的
    第一个数据为整个位图最左下角的像素颜色索引,最后一个数据时整个位图最右上角像素颜色索引

    剩下要干的事情就是直接解析位图文件到数据结构中,再从数据结构中截取出需要的部分
    并将文件头部信息原样拷贝进来,修改一下位图的高度biHeight和宽度biWidth以及文件的大小bfSize即可

    附一个详细介绍的网址,有兴趣的可以去看看
    http://baike.baidu.com/view/189487.htm

    打得我好累,呼呼~~!

    我怀疑你加载图片然后弄到ImageCreate里出了问题,因为我刚从你前面的回复中看到“通过TPicture组件LoadFromFile,再拷贝到ImageCreate中时……”,加载图片后不要拷贝到ImageCreate中,试试直接
    ImageCreate->Picture->Bitmap->LoadFromFile(…);
    或者先加载到一个bmp,然后:
    ImageCreate->Picture->Bitmap->Assign(bmp);
    如果说256色图复制颜色有这样的变化,唯一我能想到的就是做了颜色深度转换导致的误差。

  • Filed under: C++ Builder
  • [打印]关于打印~~~

    打印功能为什么我做出来的不能显示所有数据?只能打出access表中的第一条记录???
    我用的是ADOTable组件连的数据库

    是不是有什么必须设置的东西我没设置啊?

    打印前查看下数据集的数据条数,如果数据只有一条,查找你读取数据部分是不是有问题。

  • Filed under: C++ Builder
  • 最近看到一客房软件..网络闪断后不会出错,也不需要重起,很是奇怪他们是怎么实现的…莫非每条查询语句都套上try…然后用计时器不停的去尝试重新建立连接?

    应该是每次连接都判断网络,如果不通就不刷新,如果通的就连接

    发送数据请求前,检查一下是否连通

    异常保护, 出错时提示信息或记录LOG.
    这是网络软件常用方式.

    这个很容易做到。

    只要你在发送数据库操作之前,判断一下当前的连接是否正常连接上,如果不没有连接上,就重新连接一次,就OK了

    一般都是发数据的时候判断网络,另外TClientSocket在网络出问题时有OnError事件通知。

    ~~我用的ADOConnection ….没找到捕获异常的方法…大家有没有什么好的办法

  • Filed under: C++ Builder
  • 比如说我有四个字串 Str1="123.50",Str2="103.50",Str3="113.50",Str4="103.50", 然后连接成@DATA*123.50*103.50*113.50*103.50# 怎么样写才能最简单呢.

    引用 1 楼 yumikoo 的回复:
    C/C++ codeAnsiString str = "@DATA*"  +  str1 + "*"  +  str2  ……  +  str4 + "#";

    正解,如果数据太多,处理中间规律字符串部分可以使用循环。

    建议用AnsiString::sprintf,用+的话,会产生若干临时对象,速度慢,又占额外内存。

    呵呵,接分!!!

    AnsiString str = "@DATA*"  +  str1 + "*"  +  str2  ……  +  str4 + "#"; 这样是不行的,编译出错Invalid pointer addition! 呵呵,如果直接用+就能连我就不会问问题了.现在我是用 str+= "@DATA*"; str+="*",这样连,好麻烦,如果用Sprintf()该怎么写?

    C/C++ code
    void __fastcall TForm1::Button1Click(TObject *Sender) { AnsiString Str1="123.50"; AnsiString Str2="103.50"; AnsiString Str3="113.50"; AnsiString Str4="103.50"; AnsiString str = "@DATA*" + Str1 + "*" + Str2 + Str3 + Str4 + "#"; ShowMessage(str); }

    是可以连加的。

    直接加在一起就行了
    这是最简单的方法了

    恩,是可以的,我原来是AnsiString str = "@DATA"+ "*",这样不行.

  • Filed under: C++ Builder
  • 用拷贝钩子实现对文件夹的监控
    http://www.ccrun.com/article.asp?i=601&d=0z20f4
    在BCB6下成功,在2009下提示Unresolved external '_IID_ICopyHookA' referenced from…

    估计是2009对6的代码兼容不是太好吧,编译不过去。

    友情阿普
    去看看一些头文件哈,到了2009一些头文件稍微有改动的。

    #include <shlobj.h>

    实际的定义在shlguid.h

    #include <shlobj.h>已经有了。

    C/C++ code
    //.h文件: TCopyHook类实现了ICopyHook接口,TClassFactory实现了IClassFactory接口 //————————————————————————— #define NO_WIN32_LEAN_AND_MEAN #include <shlobj.h> //————————————————————————— class TCopyHook: public ICopyHook { public: TCopyHook():m_refcnt(0) {} STDMETHODIMP QueryInterface(REFIID iid,void **ppvObject); STDMETHODIMP_(ULONG) AddRef(); STDMETHODIMP_(ULONG) Release(); STDMETHODIMP_(UINT) CopyCallback(HWND hwnd, UINT wFunc, UINT wFlags, LPCTSTR pszSrcFile, DWORD dwSrcAttribs, LPCTSTR pszDestFile, DWORD dwDestAttribs); private: int m_refcnt; }; //————————————————————————— class TClassFactory : public IClassFactory { public: TClassFactory():m_refcnt(0) {} STDMETHODIMP QueryInterface(REFIID iid, void **ppvObject); STDMETHODIMP_(ULONG) AddRef(); STDMETHODIMP_(ULONG) Release(); STDMETHODIMP CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObject); STDMETHODIMP LockServer(BOOL fLock); private: int m_refcnt; };

    刚才的回复由于垃圾网站超时没了。

    有可能是因为某些预编译选项使得某些定义项被屏蔽掉了。

    找到_IID_ICopyHookA 定义的文件

    C/C++ code
    HRESULT __stdcall TCopyHook::QueryInterface(REFIID dwIID, void **ppvObject) { if(dwIID == IID_IUnknown) *ppvObject = static_cast<IUnknown*>(this); /*下面这几行不注释就会出那个错误,注释了就编译成功 else if(dwIID == IID_IShellCopyHook) *ppvObject = static_cast<ICopyHook*>(this); else return E_NOINTERFACE; //*/ reinterpret_cast<IUnknown*>(*ppvObject)->AddRef(); return S_OK; }

    刚才看了一下好象是Unicode和非Unicode乱错。

    把代码中的字符串都去掉了,TCHAR maps to wchar_t 和 char都不行。

    在任意CPP当中增加:

    C/C++ code
    const GUID IID_ICopyHookA = {0×000214EF, 0×0000, 0×0000,{ 0xc0, 0×00, 0×00,0×00,0×00,0×00,0×00,0×46} };

    增加了,错误依旧。
    太顽固了

    引用 13 楼 cczlp 的回复:
    增加了,错误依旧。
    太顽固了

    我这里添加就正常了。

    CB6的处理上面会有点不大一样,可能自动编译了相应的GUID,但是2007/2009则不会。

    另外,对于非直接使用IID_ICopyHookA 的单元当中添加上面的代码行的话,要么能够让使用者访问到该定义,要么增加extern

    比如说任意添加一个CPP写上:

    C/C++ code
    #include <guiddef.h> extern const GUID IID_ICopyHookA = {0×000214EF, 0×0000, 0×0000,{ 0xc0, 0×00, 0×00,0×00,0×00,0×00,0×00,0×46} };

    哈哈,定义IID_ICopyHookA 通过了,刚才出错是因为按UNICODE编译了。
    多谢老僵,帮了我一个大忙,我都郁闷一天了。

    引用 17 楼 cczlp 的回复:
    哈哈,定义IID_ICopyHookA 通过了,刚才出错是因为按UNICODE编译了。
    多谢老僵,帮了我一个大忙,我都郁闷一天了。

    索引你把IID_ICopyHookW也给定义上。

    添加下面完整的单元进行编译

    C/C++ code
    //GUID_CopyHook.cpp #include <guiddef.h> extern const GUID IID_ICopyHookA = {0×000214EF, 0×0000, 0×0000,{ 0xc0, 0×00, 0×00,0×00,0×00,0×00,0×00,0×46} }; extern const GUID IID_ICopyHookW = {0×000214FC, 0×0000, 0×0000,{ 0xc0, 0×00, 0×00,0×00,0×00,0×00,0×00,0×46} };

    OK了。
    居然不能结帖,等明天再试试。

    引用 20 楼 cczlp 的回复:
    OK了。
    居然不能结帖,等明天再试试。

    可能是嫌你放的分数不够…

    难怪官方声称CB后来的版本比6编译快,原来有些东西根本就没有编译。

    引用 22 楼 cczlp 的回复:
    难怪官方声称CB后来的版本比6编译快,原来有些东西根本就没有编译。

    不是没有编译,只是处理逻辑上面的问题。GUID的定义都是在头文件当中,如果把头文件当中的声明按宏来处理,那么就要对这些GUID分配空间,如果使用到该宏定义的地方比较多,并且没有进行相应的预编译控制的话,编译器进重复定义的扫描工作量会相当大,并且对于程序来讲也是不清晰的。因为程序员压根儿就不知道这部分内存分配在哪里。

    而对于给程序当中不需要用到的东西分配空间也是毫无价值的。

    cb2009用得不爽,不是这一次了,总是出现一些小问题。看来稳定的路还很长。

    D2009还是不错的

  • Filed under: C++ Builder
  • 问个问题

    这样得不到正确结果

    C/C++ code
    //————————————————————————— #include <stdio.h> #pragma hdrstop //————————————————————————— #pragma argsused void swap(double *a1,double *a2) { double *b; *b = *a1; *a1= *a2; *a2= *b; } int main(int argc, char* argv[]) { double h1=0.1f; double h2=5.1f; swap(&h1,&h2); printf("%f,%f",h1,h2); // cout<<h1,h2<<endl; getchar(); return 0; } //—————————————————————————

    这样就可以,是什么原因呢?

    C/C++ code
    //————————————————————————— #include <stdio.h> #pragma hdrstop //————————————————————————— #pragma argsused void swap(double *a1,double *a2) { double b; b = *a1; *a1= *a2; *a2= b; } int main(int argc, char* argv[]) { double h1=0.1f; double h2=5.1f; swap(&h1,&h2); printf("%f,%f",h1,h2); // cout<<h1,h2<<endl; getchar(); return 0; } //—————————————————————————

    double *a1就是h1,是double型变量,而*b是指针变量b所指向的变量,于是b中并没有确定的地址值,他的值是不可预见的,b所指向的单元也是不可预见的、因此对*b的复制可能破坏系统正常的工作情况。
    另外,如果你期望把b当作是指针,本题可以另一种方式表达

    C/C++ code
    void swap(double *a1,double *a2) { double *b; b = a1; a1= a2; a2= b; } int main(int argc, char* argv[]) { double h1=0.1f; double h2=5.1f; swap(&h1,&h2); printf("%f,%f",h1,h2); getchar(); return 0; }

    double *a1就是h1,是double型变量,而*b是指针变量b所指向的变量,于是b中并没有确定的地址值,他的值是不可预见的,b所指向的单元也是不可预见的、因此对*b的复制可能破坏系统正常的工作情况。
    另外,如果你期望把b当作是指针,本题可以另一种方式表达

    C/C++ code
    void swap(double *a1,double *a2) { double *b; b = a1; a1= a2; a2= b; } int main(int argc, char* argv[]) { double h1=0.1f; double h2=5.1f; swap(&h1,&h2); printf("%f,%f",h1,h2); getchar(); return 0; }

    引用 2 楼 yumikoo 的回复:
    double *a1就是h1,是double型变量,而*b是指针变量b所指向的变量,于是b中并没有确定的地址值,他的值是不可预见的,b所指向的单元也是不可预见的、因此对*b的复制可能破坏系统正常的工作情况。
    另外,如果你期望把b当作是指针,本题可以另一种方式表达

    C/C++ code
    void swap(double *a1,double *a2)
    {
      double *b;
      b = a1;
      a1= a2;
      a2= b;
    }

    int main(int argc, char* argv[])
    {
      double h1=0.1f;

    你在swap函数里将a1和a2的地址换一下干什么?在swap函数里这两个指针变量都是局部的,换过来也没用啊。

    同意1樓的看法!!!!

    谢谢大家的参与!

  • Filed under: C++ Builder
  • 我用的是BCB5.0、BDE的paradox数据库,Table控件,在从软件把数据导入到数据库以后,若在软件里面更改或者添加、删除了数据,如何使得数据库里面的数据同步更新? 请详细解答 感激不尽

    那我不如再导入一次老~~~

    C/C++ code
    /* 不明白你指的同步更新 一般你用Append,或者Edit()方法操作记录后, Post()下 或者你用SQL语句修改 更新记录后 最好再关闭下Query或Table,再打开Query或Table */

    –下面应该也可以.
    Table1->Refresh()

    Table1->FlushBuffers();可以把缓存中的数据立即写到数据库中,这样就保持了同步更新

    引用 3 楼 jxw1987628 的回复:
    C/C++ code/*
    不明白你指的同步更新

    一般你用Append,或者Edit()方法操作记录后,
    Post()下

    或者你用SQL语句修改 更新记录后

    最好再关闭下Query或Table,再打开Query或Table

    */


    Table->CLOSE();
    Table->OPEN();
    Table->LAST();

  • Filed under: C++ Builder
  • 用的是BDE的paradox数据库 Table控件。
    每次导入数据如果是重复的数据就不做动作,若不是重复的数据则覆盖更新。

    mark

    那有什么好的办法没有~~

    用sql语句来控制

    你怎么判断是重复数据,不可能一个个字段比较

    如果数据库本身也是由你来控制的话,可以加个标识变量,如果更新过了就打开标识。
    导入之前先检查这个标识。

    如何加这个标识变量 请举个例子~~

  • Filed under: C++ Builder
  • 类别

    最新

    标签

    链接


    存档