我爱builder

C++Builder 程序员博客

写了一个函数判断子窗口是否已经打开
bool OpenForm(TFrom *WFrom)
{
int i;
bool FromExist;
if(WForm==NULL) return false;
FormExist=false;
for(i=0;i <Screen->FormCount;i++)
{
if(Screen->Forms[i]->ClassType()==WForm->ClassType)
{
FormExist=true;
break;
}
}
if(FormExist==false) return FormExist;
if(WForm->WindowState==wsMinimized)
ShowWindow(WForm->Handle,SW_SHOWNORMAL);
else
ShowWindow(WForm->Handle,SW_SHOWNA);
if(!WForm->Visible) WForm->Visble=true;
WForm->BringToFront();
WForm->SetFocus();
return true;
}

下面是函数的调用
if(OpenForm(Form2)==false)
{
From2=new TForm2(this);
Form2->Parent=this->Parent;
Form2->Show();
}
运行编译通过,在链接的时候就出错显示
[ILINK32 Error]Error:Umresolved external 'TForm1::OpenFrom(Froms::TForm*)'referenced from D:\DEBUG\UNIT1.OBJ
单独运行函数不会出错,一调用函数就出错。

删除了,还是出错

原因是你的函数声明时,把OpenForm作为了Form的成员函数

C/C++ code
class TForm1:public TForm { private: //user declared __published public: bool OpenForm(TFrom *WFrom) ; }

而你在写OpenForm的实现函数时,却又没有写上TForm1这个类域的名字,它只看到了声明,当然连接不到你的实现体的代码!

所以把

C/C++ code
bool OpenForm(TFrom *WFrom) { int i; bool FromExist; if(WForm==NULL) return false; FormExist=false; for(i=0;i <Screen->FormCount;i++) { if(Screen->Forms[i]->ClassType()==WForm->ClassType) { FormExist=true; break; } } if(FormExist==false) return FormExist; if(WForm->WindowState==wsMinimized) ShowWindow(WForm->Handle,SW_SHOWNORMAL); else ShowWindow(WForm->Handle,SW_SHOWNA); if(!WForm->Visible) WForm->Visble=true; WForm->BringToFront(); WForm->SetFocus(); return true; }

改成

C/C++ code
bool TForm1::OpenForm(TFrom *WFrom) { int i; bool FromExist; if(WForm==NULL) return false; FormExist=false; for(i=0;i <Screen->FormCount;i++) { if(Screen->Forms[i]->ClassType()==WForm->ClassType) { FormExist=true; break; } } if(FormExist==false) return FormExist; if(WForm->WindowState==wsMinimized) ShowWindow(WForm->Handle,SW_SHOWNORMAL); else ShowWindow(WForm->Handle,SW_SHOWNA); if(!WForm->Visible) WForm->Visble=true; WForm->BringToFront(); WForm->SetFocus(); return true; }

太谢谢你了,真是高手,一眼就看出了问题

  • Filed under: C++ Builder
  • 好象要通过读注册表,谁能给出cb的原码

    要查看哪些值,能不能给我原码

    请大家帮忙啊

    名字和我差不多的哦,哈哈
    帮你顶下

    大家帮帮忙啊,

    你可以到国外的网站上找找,我看到过,但是忘了在哪里的,我是在google上搜索到的,不知道当时是搜索什么,不好意思!

  • Filed under: C++ Builder
  • 如题 我想在窗口中将所有是button类型按钮 放到数组中,中间要有个这样的判断语句 我对控件不是很清楚他们是怎么判断 最好能举个列子 谢了

    也可用

    C/C++ code
    if(dynamic_cast<TButton*>Form1->Components[i]) { TButton *pBtn=(TButton*)(Form1->Components[i]); // ….. }

    刚才我试了下 发现[jxw1987628]的代码给我了点想法,
    我打算使用TWinControl这样操作
    for(int I=0;I <this->ControlCount;I++){
                    TWinControl *Temp=dynamic_cast <TWinControl *>(this->Controls[I]);
                    if(Temp->ClassNameIs("TButton"))
                            ShowMessage("呵呵终于找到你了Button");
    }
    结果给我报了地址引用错误。我不明白了

    你应该用TComponent
    大概如下

    C/C++ code
    if ( ComponentCount > 0 ) { for ( int i = 0 ;i< ComponentCount ;i++ ) { Temp = Components[i]; if (Temp->ClassNameIs("TForm2")) { ShowMeaasge( dynamic_cast<TForm2 *>(Temp)->Caption ) } } }

    引用 3 楼 loxiro 的回复:
    刚才我试了下 发现[jxw1987628]的代码给我了点想法,
    我打算使用TWinControl这样操作
    for(int I=0;I <this->ControlCount;I++){
                    TWinControl *Temp=dynamic_cast <TWinControl *>(this->Controls[I]);
                    if(Temp->ClassNameIs("TButton"))
                            ShowMessage("呵呵终于找到你了Button");
    }
    结果给我报了地址引用错误。我不明白了

    你的用法不对,先看看dynamic_cast的意义!,

    用dynamic_cast是标准的用法,原因是:如果我声明了TMyButton:TButton,那么用ClassNameIs就会失败,但是用dc用dynamic_cast就不会。

    既然都用dynamic_cast了,那就不需要ClassNameIs了,直接

    C/C++ code
    for(int I=0;I <this->ControlCount;I++){ if(dynamic_cast <TButton*>(this->Controls[I])) ShowMessage("呵呵终于找到你了Button"); }

    感谢大家的帮忙 dynamic_cast我知道怎么用了 难道我下次遇到个checkbox DBGrid 都要用dynamic_cast来转换.本着对技术或知识的追逐我还是想问下Components和TWinControl 有什么区别阿 为什么我用TWinControl 就不能像1楼和2楼那样操作呢

    象按钮,下拉框这种Windows里自带的控件,VCL对它做了一个包装,这些都是从TWinControl继承的
    另外还有更多的是VCL自己特有的组件,如TImage,TDataSource,TIdFTP等等。
    而所有的VCL组件(可以从面板上拖拉的,当然也包括前面说的TWinControl)都是从TComponent继承的。
    A->Controls是查找Parent是A的控件,A->Components是查找Owner是A的控件。
    说得不周到之处后面补充哈

    是不是TButton
    Object->ClassNameIs("TButton");
    是不是继承于TButton
    Object->InheritsFrom(__classid(TButton));//相当于Delphi的Object Is TButton

    to(Waiting4you);让我看到一丝曙光
    刚从帮助中发现,也不知道我这样理解的可以不,TButton是从TButtonControl那继承,TButtonControl又是继承自TWidgetControl,后再继承于TControl ,这样一层一层继承TControl <-TComponent <-TPersistent <-TObject.
    而我拖出来的一个Button难道是从TButton的一个对象吗?这样只要是基类对子类动态调用都可以从判断中得到是不是TButton的类型,另外让我发现 使用的ClassNameIs(const AnsiString string)方法是由TObject定义的,TObject? TObject?他是干什么的呢?还有他定义的一些方法?很怪!
    我只能说自己开始刚接触bcb,不过这里的继承使用的让我眼花缭乱,我还是想知道这写基础类的作用,不知道那位能帮我说说。感觉顿顿的,需要有人来捅下,才能清醒。

    先学好C++基础,了解虚方法

  • Filed under: C++ Builder
  • 如题,我在工具栏放了一个按钮,用于导出DBGridEH中的数据.

    我采用的是多页面,即:一个窗口中有多页,每页上都有DBGridEH组件,这样当单击按钮时怎样判断要导出的数据是哪一个DBGridEH组件?

    引用 1 楼 i_love_pc 的回复:
    可以设置一个标示变量,当这一页激活的时候设置该变量的值,然后通过该变量来对应DBGridEH。

    还可以根据tabindex的值判断,思路一样。

    你用什麼導出來?fastreport? EXECL?
    可以DATESET指定數據源呀

    ActiveControl属性就是指当前活动的组件!

    TPageConrt有ActiverPage可以判断激活页面

    active

    枚举窗体上所有的组件,判断类名为TDBGridEh并且父窗口为PageControl->ActivePage的就是当前显示出来的DBGridEh了。

    举个简单例子:

    C/C++ code
    TDBGridEh *dbgrd = NULL; for(int i=0; i<PageControl1->ActivePage->ControlCount; i++) { if(PageControl1->ActivePage->Controls[i]->ClassNameIs("TDBGridEh")) { dbgrd = (TDBGridEh *)PageControl1->ActivePage->Controls[i]; break; } } if(dbgrd) ShowMessage(dbgrd->Name);

    ActivePageIndex可以查到活动的

    首先感谢大家,可能又是我没说完整的原因,
    ActivePageIndex、PageControl1->ActivePage虽然能判断当前活动的页从而找出活动页上的TDBGridEh组件。

    但是,如果同一页里有多过TDBGridEh组件该怎么办呢?

    把要导出的DBGridEh作个记号,比如Tag设为1之类的。然后在循环中判断了组件的类名后再判断该组件的Tag是否为需要导出的DBGridEh。

  • Filed under: C++ Builder
  • 我的表格里面有个name姓名字段,里面有几千行记录,我如何用sql语句快速的判断这些name字段里面是否有相同的名字存在(因为正常情况之下不应该有相同的名字)?

    更简单点的:
    select name from table
    group by name
    having count(name)>1

    引用 2 楼 whomin 的回复:
    更简单点的:
    select name from table
    group by name
    having count(name)>1

    学习

    2楼的办法不错

    学习

    该回复于2008-07-26 22:45:57被版主删除

  • Filed under: C++ Builder
  • 请问判断文件存在用那个函数,参数分别是什么?

    楼上似乎理解错了,他问用什么函数判断文件是否存在:

    FileExists(文件名)

    很简单的一种办法:

    #include <iostream>
    #include <fstream>
    using namespace std;
    #define FILENAME "stat.dat"
    int main()
    {
        fstream _file;
        _file.open(FILENAME,ios::in);
        if(!_file)
        {
            cout < <FILENAME < <"没有被创建";
          }
          else
          {
              cout < <FILENAME < <"已经存在";
          }
          return 0;
    }

    extern PACKAGE bool __fastcall FileExists(const AnsiString FileName);

  • Filed under: C++ Builder
  • 全国的区号有190个
    手机号码有:
    1300000-1399999
    1530000-1534999
    1560100-1569949
    1580030-1599999

    写了两个正则表达式来判断
    电话
    (0(4(8(8[78]|2|31)|4[08]|2(1|66|[79])|3[123456789]|[157][0123456789])|6(9[12]|3[12345]|6[01238]|22|88)|3(9[1234568]|86[234678]|[157][0123456789]|235|35|49)|8(2(4[17]|9[12347]|1[2367]|3[012567]|6[0789]|7[06789]|8[23456789]|2[0123456789]|55?)|6(3[12345]|7[01234567]|1[09]|6[2345679]|8[0126789]|[245][0123456789])|0(1[5678]|4[09]|6[12479]|5[14679]|78|81)|4(2[03]|6[12356]|4[04567]|[05][35678]|3[0145678]|1[1245789]|89|93)|8[13678]|1[12345678]|9[01234589]|5[123456789]|[37][0123456789])|5(4[36]|6([12456]|33?)|2[037]|9[123456789]|[1357][0123456789]|80)|9(2(4[0234]|2[012345789])|4(8[234]|2[123456]|[04][1234567]|[19][12345678]|6[36789]|75|3[123456]?)|8(3[1239]|2[089]|4[01246789])|5[1234]|0(0[39]|[23]|81|9)|1[012345679]|3[123456789]|[79][0123456789])|7(4[3456]|2[248]|6[0235689]|[13579][0123456789]|01)|2[012345789]|10))\d{7,8}

    手机
    (15[8-9][0-9][0-9][0-9][0-9]\d{4}|13[0-9][0-9][0-9][0-9][0-9]\d{4}|153[0-4][0-9][0-9][0-9]\d{4}|156[0-9][1-9][0-4][0-9]\d{4})

    在此特别感谢阿水:http://www.regexlab.com/
    他写的DEELX   正则表达式引擎实在太强了.

    你够强~

    不是我强,是regexlab.com的DEELX   正则表达式引擎强,

    (010|020|030|区号列表)\d{7,8}

    将190多个区号一一列出,
    他附带的一个调试工具给优化过就成了这样的表达式了

    不懂

    好。

    都强!

    牛X

    好!

    呃   固定电话没有1开头的。

    除了特殊号码   110   120之类的。

    你够强~

    没有1开头的固定电话吧

    好东西

    100-129专用
    130-189移动通信
    190-199特用
    其它固话

    看不懂

  • Filed under: C++ Builder
  • 在网上搜索了一下除了说后缀名好像没有其他什么好的办法,可是缀名是不准备的,比如说RM既有音频又有视频,所以说哪位知道应该怎么样区分吗?就像暴风影音一样.知道原理的也来聊一下呀

    看来你要从头开始学习视频开发了.
    熟悉编解码了.

    能指点一下吗谢谢….

    应该有些帧头信息数据吧 ,就比如MP3咯,它也有些帧头信息。

    能说一下这些信息怎么读取吗?谢谢

  • Filed under: C++ Builder
  • CreateProcess(NULL,sCommandLine.c_str(),&sa,&sa,TRUE,CREATE_NO_WINDOW,NULL,NULL, &si, &pi);
    请问:怎么判断这个进程已经执行完毕?

    多谢楼上.

    不过会阻塞主线程.
    有没有办法不阻塞主线程查询一个进程是否执行完毕?

    如果动态创建一个子线程,再再子线程中等待 另外一个进程执行完毕,这样就不怕阻塞了.

    请问这样好实现吗?
    主线程怎么传递参数到子线程?子线程怎么返回参数到主线程?

    发送消息通知主线程

    1楼、3楼正解。
    主线程创建子线程时就可以传参数(通过构造函数即可),子线程通过发送消息来通知主线程。

    多谢讲解.

    1.有没有办法不阻塞主线程查询一个进程是否执行完毕?

    2.创建一个线程,在构造函数里面转递参数?怎么实现?
      能否给个简单代码示例?

    3.发送消息通知主线程?
    能否给个简单代码示例.

    才学C++BUILDER,已经买了3本C++BUILDER的书,但书上都没有讲Windows API以及进程,线程.
    请问,这些类容哪里可以找到参考资料?或者推荐本书?

    IsRunCompleted = WaitForSingleObject(Thread->Handle,0)!=WAIT_TIMEOUT;

    线程构造函数传参数的方法:
    class TThreadA : public TThread
    {
    public:
        __fastcall TThreadA(bool CreateSuspended,此处放从主线程传过来的参数):TThread(true)
        {
            //此处可以将主线程传入的参数用变量存储
        };
    }
    主线程在创建该线程时传入参数即可

    关于消息处理:
    1.主线程类需要做的事情:
    自定义一类新消息,代表所关注进程结束:
      #define WM_MYMESSAGE (WM_USER+100)
    在主线程声明中建立消息映射表,把某条消息的处理权交给自定义的消息处理函数。
      BEGIN_MESSAGE_MAP
      MESSAGE_HANDLER(WM_MYMESSAGE,TMessage,消息处理函数名)
      END_MESSAGE_MAP(TForm)
    在主线程类中声明消息处理函数:
      void __fastcall 消息处理函数名(TMessage &Message);
    并在cpp中具体写出消息处理函数,在这里实现你需要的功能。比如:
      void __fastcall TMainForm:: 消息处理函数名(TMessage &Message)
      {
        …    // 此时已得知关注进程结束,在此加入你自己的处理代码
        TForm::Dispatch(&Message); //如果不是自定义消息,则最好继续往后传递
      }
    2.子线程如何传递消息:
      PostMessage(主线程句柄,WM_MYMESSAGE,0,0);

  • Filed under: C++ Builder
  • 请问如何判断鼠标消息是否在窗口内?我知道如何拦截窗口外鼠标,但是不知道拦截到了之后LOWORD(lParam)和HIWORD(lParam)的值是窗口坐标的值还是屏幕坐标的值,要怎么判断呢?还有就是在窗口外拦截后产生的消息是MOUSEMOVE吗??

    鼠标在窗口内移动产生的是MOUSEMOVE消息没错啊

    获得当前鼠标所在的坐标值,然后与窗口坐标比较,就能判断是不是在窗口内了。

    1.PtInRect
    2.对于客户区消息是窗口坐标,对于非客户区消息是屏幕坐标。
    3.窗口过程通常只响应鼠标处于客户区和非客户区的消息,对于窗口外的消息需要自己手动捕获。

    谢谢你们回答我的问题,我想补充以下问题会比较清楚,我现在是想在一个没有标题栏的窗口上实现像内定窗口那样的移动功能,也就是说我设了一个和一般标题栏大小位置一样的区域在窗口上方
    RE  anarki1234 :但是我还有些没有搞明白,你说获得鼠标现在的坐标值去和窗口坐标做对比,但是前提是我必须知道此刻我捕捉的是不是窗口外消息(因为屏幕坐标和显示区域坐标是不一样的),我要如何判断现在我捕获的是不是窗口内的消息。
    RE eternalkid :我现在已经捕捉了窗口外的消息,但是问题就是捕捉完产生的消息类型是什么?坐标值是显示区域坐标还是屏幕坐标?

    你若是只想实现类标题栏的移动功能,直接处理WM_NCHITTEST就可以了。
    因为是非客户区的消息,所以获得的LPARAM里面存储的鼠标坐标是屏幕坐标。

    现在我是这么写:
    case WM_NCHITTEST:
    ptTitle.x=393;
    ptTitle.y=26;
    ScreenToClient(hwnd,&ptTitle);
    ptMouse.x=LOWORD(lParam);
    ptMouse.y=HIWORD(lParam);

    if((ptMouse.x <ptTitle.x)&&(ptMouse.x>0)&&(ptMouse.y>0)&&(ptMouse.y <ptTitle.y))
    {  Rectangle (hdc, 0, 0, 100, 100) ;
    InvalidateRect(hwnd,NULL,FALSE);
    return HTCAPTION;

    }

    那如果热点不在我定义的这个范围内的话这个消息要返回什么呢?

    首先你的代码里有个错误:

    引用 7 楼 old_guy 的回复:
    现在我是这么写:
    case WM_NCHITTEST:
    ptTitle.x=393;
    ptTitle.y=26;

    ptMouse.x=LOWORD(lParam);
    ptMouse.y=HIWORD(lParam);

    ScreenToClient(hwnd,&ptMouse);

    if((ptMouse.x <ptTitle.x)&&(ptMouse.x>0)&&(ptMouse.y>0)&&(ptMouse.y <ptTitle.y))
    {  Rectangle (hdc, 0, 0, 100, 100) ;
    InvalidateRect(hwnd,NULL,FALSE);
    return HTCAPTION;

    }

    那如果热点不在我定义的这个范围内的话这个消息要返回什么呢?…


    需要转化成窗口坐标的应该是你的鼠标坐标才对。
    剩下的交给你重载的默认的窗口过程处理就行了啊!

    很谢谢你的回答,但是我用的是C语言,没有重载这个概念,我不知道C语言要怎么处理。你可以加下我的Q吗?573301735
    还有一个问题就是,我在程序里响应鼠标按键消息,按钮(自己画的按钮)的区域在  WM_NCHITTEST 响应里要返回什么值程序才能收到WM_LBUTTONDOWN消息?

    很麻烦你,我再开个帖子给分

    如果你是用的纯C,没用VCL和MFC,那么你的窗口过程函数因该是类似以下形式:

    C/C++ code
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { ……..//定义变量 switch(message) { case WM_NCHITTEST: ……//处理消息 } [color=#FF0000]return DefWindowProc(hwnd,message,wParam,lParam);//这就是系统默认窗口过程函数,用这个返回就好[/color] }

  • Filed under: C++ Builder
  • 类别

    最新

    标签

    链接


    存档