我爱builder

C++Builder 程序员博客

VCL是不允许直接对MDIChild子窗体进行ShowModal()的,而且如果让MDIChild成为整个应用程序的模态窗口似乎也没什么意义。
我看见过一些程序(不是BCB或Delphi写的),在一个子窗体Form1中ShowModal另一个子窗体Form2,此时的Form1是不响应操作的(只能先关闭Form2),而另一个子窗体Form3和主窗体是可以响应的。
我想这在BCB下肯定也可以实现吧?

把Enabled设为false恐怕不合适,因为我不知道Form2什么时候关闭,如果在Form2的OnClose事件中写Form1->Enabled=true;有几点不妥:
1.将使程序变得复杂,不符合模块高内聚低耦合的原则.
2.而且Form2也不一定由Form1打开,也许被直接打开或第三者打开或者不是模态显示.
3.Form2被ShowModal后必须在Form1上层显示,但其他Form可以把它覆盖。
3.再者我希望它返回ModalResult。

我不一定要使用ShowModal这个函数,肯定应该有API可以实现的吧,有些软件更牛,当ShowModal了另一个子窗体后,虽然自己的界面不能响应,但窗口标题还是可以响应,可以最大化和移动等。

可以使用API函数:SetWindowPos()
设置置顶:SetWindowPos(form2->hwnd, -1, 0, 0, 0, 0, 3)
取消置顶:SetWindowPos(form2->hwnd, -2, 0, 0, 0, 0, 3)

我不是要它置顶,而是要它对于建立它的Owner窗体来说是模态显示的,即不关闭是不能响应Owner窗体的点击的,但其他窗体不受限制。

该回复于2008-07-10 02:43:22被版主删除

楼主说的是非MDI程序中 确实是可以的,

正如1楼的 所述。。showmodal的说明!

前面的人说的很多了

学习啦

楼主说的是非MDI程序中 确实是可以的,

  • Filed under: C++ Builder
  • 按钮如何打开另外一个窗体同时关掉本窗体??
    谢谢
    这问题很菜对吧!

    xxx->Show();
    Close();

    如果本窗体是主窗体,就不行了
    那只能
    ***->Show();
    this->Hide();

    哦,搞错了,不能是this,应该是form名

    哈哈  谢谢
    这个论坛看来不错啊
    我以后常来!

    这问题看上去很菜,其实不菜的。
    几乎所有的菜鸟都碰到过(呵呵,我也想过)。

    1、如果是非主窗体起动另一窗体后自个关闭,这个很容易,直接写代码1->Show();2->Close();
    2、至于主窗体,那是不能关闭的,只能是Hide(),也就是藏起来。如果你实在要关了主窗,那就不是关的概念了,那是主进程替换,这玩意儿难度就大了,记得查过相关资料,但本人没搞出个所以然来,你如果有兴趣可以去查查看,似乎很难的。

    应该不存在"主进程替换"的概念吧,不好意思,我还是第一次听到这个词

    这只是一个消息循环的问题,BCB的main函数WinMain中没有消息循环,其消息循环函数在TApplication类中,而TApplication又把消息循环的控制权交给了Application中第一个CreateForm的TForm对象,当这个TForm关闭后,Application中的消息循环就结束了,程序自然就退出了,而其它的Form,因为考虑到资源重用,在调用Close()时其实窗口并未Destroy,只是简单的Hide了,如果你要关掉Main TForm再打开其它Form,那就只能用Hide()了

    各位老大理解复杂了吧?"按钮如何打开另外一个窗体同时关掉本窗体??"是什么意思?是打开自身的"窗体"还是打开外部的程序?
    要是打开外部的程序是很简单:
    ShellExecute(Handle, "Open","文件名", NULL, NULL, SW_SHOW);//打开外部程序
    PostMessage(Handle, WM_SYSCOMMAND, SC_CLOSE, NULL);//关闭当前窗口.
    要是前后打开的是一个程序的不同窗体,那很麻烦的,需要调用拷贝自身然后用复制品把自己消灭掉,具体程序在老妖的站里面有详细的介绍.

    大家想的都复杂了哦

    程序启动时把主Form隐藏,在关闭这个窗体时打开隐藏窗体就可以了….

    直接写代码1-> Show();2-> Close();

    我想LZ可能是在设计一个类似密码权限的窗口,密码通过后密码界面关闭,将被操作的窗口显示。
    如果这样的话密码窗体就可能是modal形式,那关闭可能会麻烦点。
    1.密码窗体“确定”键的ModalResult==mrOk,“取消”键的ModalResult==mrCancel
    2.void __fastcall T密码窗体::FormCloseQuery(TObject *Sender, bool &CanClose)
    {
    if(ModalResult==mrOk && EditKey->Text!="123456")
            {
            Application->MessageBoxA("密码输入错误,请重新输入","提示",64);
            EditKey->Text="";
            CanClose=false;
            } 
    }
    3.void __fastcall TMainForm::ShowClick(TObject *Sender)
    {
          if (T密码窗体->ShowModal()==mrOk)
          {
            T即将操作窗体->ShowModal();
            }
    }

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

    学习中。。。。。。学习中。。。。。。

    如果消息机制不会的话 用控件完全可以实现 BCB的控件是独步天下的

    xxx->Show();
    Close();//关闭

    xxx->Show();
    Hide();//隐藏


    如果消息机制不会的话 用控件完全可以实现 BCB的控件是独步天下的

    //关闭所有子窗体
        nCount=this->MDIChildCount;
        i=0;
        while(i <nCount){
            this->MDIChildren[i]->Close();
            i++;
        }

    我想LZ的问题没有这么复杂吧,也想不到有这么复杂的解决办法,学习ING……

    收藏学习

  • Filed under: C++ Builder
  • Form1中有一个变量a,
    如果在Form2中调用a的值应该怎么做?

    把变量a弄为公共的,然后在Form2包含Form1头文件,然后Form1->a 就可以了
    不过不建议这样做,最好的就是在Form1弄两个接口函数,一个get 一个set 这样比较好

    本人新人,最好写上代码

    已經有人回答了。如果還不懂,該溫習一下書。隨便找本 C++  或 BCB 的書  過一遍就懂了

  • Filed under: C++ Builder
  • 设计的一个应用程序中用了两个Form,其中第二个Form中有一个Combobox,当我显示第二个form的时候,Combobox中的内容自动变成蓝色,也就是好像自动获取了焦点。我在第二个form中的显示事件中设置其他组建获得焦点,结果仍然是那个Combobox获得焦点。这是怎么回事呢?如果让Combobox不自动获得焦点?

    很好。谢谢。搞定了。

  • Filed under: C++ Builder
  • 实现功能: 打印窗体

    问题:   

    在我的电脑上编译后运行,打印出错,错误请看下面代码。
    在其他电脑上编译后运行,打印正常。
    在其他电脑上不编译直接运行我的程序,打印出错。

    (公司的电脑都测试了下,几台正常,几台出错)

    代码如下:

    Unit1.h

    C/C++ code
    //————————————————————————— #ifndef Unit1H #define Unit1H //————————————————————————— #include <Classes.hpp> #include <Controls.hpp> #include <StdCtrls.hpp> #include <Forms.hpp> #include <Dialogs.hpp> //————————————————————————— class TForm1 : public TForm { __published: // IDE-managed Components TButton *Button1; TPrintDialog *PrintDialog1; void __fastcall Button1Click(TObject *Sender); private: // User declarations public: // User declarations __fastcall TForm1(TComponent* Owner); void Print_SW(Graphics::TBitmap * Bitmap); //2007/11/30 add by shiwei<– BITMAPFILEHEADER * DibLoadImage (PTSTR pstrFileName); }; //————————————————————————— extern PACKAGE TForm1 *Form1; //————————————————————————— #endif

    Unit1.cpp

    C/C++ code
    //————————————————————————— #include <vcl.h> #pragma hdrstop #include "Unit1.h" //————————————————————————— #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //————————————————————————— __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //————————————————————————— void __fastcall TForm1::Button1Click(TObject *Sender) { int nWinState; if(PrintDialog1->Execute()) { Graphics::TBitmap *formbmp, *temp; formbmp = new Graphics::TBitmap(); temp = new Graphics::TBitmap(); try { Button1->Visible = false; nWinState=this->WindowState; this->WindowState = wsMaximized; temp = GetFormImage(); formbmp->Width = ClientWidth; formbmp->Height = ClientHeight; TRect tmpRec; tmpRec.Top = 1; tmpRec.Left = 1; tmpRec.Right = ClientWidth; tmpRec.Bottom = ClientHeight; formbmp->Canvas->CopyRect( ClientRect, temp->Canvas, tmpRec ); Print_SW(formbmp); } __finally { this->WindowState =nWinState; delete formbmp; delete temp; } } } void TForm1::Print_SW(Graphics::TBitmap * Bitmap) { static BITMAPFILEHEADER * pbmfh ; static BITMAPINFO * pbmi ; static BYTE * pBits ; static int DIBWidth, DIBHeight, PrintWidth, PrintHeight; Bitmap->SaveToFile(".\\~tmp.bmp"); // Load the entire DIB into memory AnsiString TmpStr = GetCurrentDir()+"\\~tmp.bmp"; pbmfh = DibLoadImage(TmpStr.c_str()); //Get pointers to the info structure & the bits pbmi = (BITMAPINFO *) (pbmfh + 1) ; pBits = (BYTE *) pbmfh + pbmfh->bfOffBits ; // Get the DIB width and height if (pbmi->bmiHeader.biSize == sizeof (BITMAPCOREHEADER)) { DIBWidth = ((BITMAPCOREHEADER *) pbmi)->bcWidth ; DIBHeight = ((BITMAPCOREHEADER *) pbmi)->bcHeight ; } else { DIBWidth = pbmi->bmiHeader.biWidth ; DIBHeight = abs (pbmi->bmiHeader.biHeight) ; } PrintHeight = Printer()->Canvas->ClipRect.Height(); PrintWidth = Printer()->Canvas->ClipRect.Width(); Printer()->BeginDoc(); SetStretchBltMode(Printer()->Canvas->Handle,COLORONCOLOR); StretchDIBits( Printer()->Canvas->Handle, 0, 0, PrintWidth, PrintHeight, 0, 0, DIBWidth, DIBHeight, pBits, pbmi, DIB_RGB_COLORS, SRCCOPY ); Printer()->EndDoc(); if (pbmfh) free (pbmfh) ; DeleteFile(TmpStr); } //————————————————————————— BITMAPFILEHEADER * TForm1::DibLoadImage (PTSTR pstrFileName) { BOOL bSuccess ; DWORD dwFileSize, dwHighSize, dwBytesRead ; HANDLE hFile ; BITMAPFILEHEADER * pbmfh ; hFile = CreateFile (pstrFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL) ; if (hFile == INVALID_HANDLE_VALUE) return NULL ; dwFileSize = GetFileSize (hFile, &dwHighSize) ; if (dwHighSize) { CloseHandle (hFile) ; return NULL ; } pbmfh =(BITMAPFILEHEADER *)malloc(dwFileSize) ; if (!pbmfh) { CloseHandle (hFile) ; return NULL ; } bSuccess = ReadFile (hFile, pbmfh, dwFileSize, &dwBytesRead, NULL) ; CloseHandle (hFile) ; if (!bSuccess || (dwBytesRead != dwFileSize) || (pbmfh->bfType != * (WORD *) "BM") || (pbmfh->bfSize != dwFileSize)) { free (pbmfh) ; return NULL ; } return pbmfh ; }

    根据进去后 发现我的电脑上问题出现在这里:

        if (!bSuccess &brvbar &brvbar (dwBytesRead != dwFileSize)       
                      &brvbar &brvbar (pbmfh->bfType != * (WORD *) "BM")
                      &brvbar &brvbar (pbmfh->bfSize != dwFileSize))
        {
              free (pbmfh) ;
              return NULL ;
        }

    中的 (pbmfh->bfSize != dwFileSize) 不相等,所以返回了NULL;
    但是其他电脑上(pbmfh->bfSize != dwFileSize) 相等,执行打印正常。

    大家帮忙测试下,看看是什么问题!!!谢谢!!

    是不是你的打印机上的驱动没有安好?

    晕,你没仔细看我的写的东西,驱动正常的

    电脑无打印机噢。。搞不起来噢。。

    首先,确定你的BCB引用的头文件路径正确,库文件路径正确(%BCB%\include,%BCB%\lib应该写在其它路径前面)

    然后,找到BITMAPFILEHEADER的声明部分(应该在wingdi.h里),在它的前面写上#pragma pack(push,2),后面写上#pragma pack(pop)再试试。

    引用 4 楼 jacknes009 的回复:
    电脑无打印机噢。。搞不起来噢。。

    可以用微软的虚拟打印机调试的

    不知道为什么 我的电脑上 :

    pbmfh =(BITMAPFILEHEADER *)malloc(dwFileSize) ;
    bSuccess = ReadFile (hFile, pbmfh, dwFileSize, &dwBytesRead, NULL) ;
    返回值1,成功,但是读进来的值pbmfh 的size很小,只有几十,和dwFileSize(几百万)无法相比。

    其他电脑上这两个值是相等的。

    我觉得应该就是字节对齐的问题,在偶的电脑上试也木有问题,你干脆直接重新定义BITMAPFILEHEADER吧:
    #pragma pack(push,2)
    struct MYBITMAPFILEHEADER {
            WORD    bfType;
            DWORD  bfSize;
            WORD    bfReserved1;
            WORD    bfReserved2;
            DWORD  bfOffBits;
    };
    #pragma pack(pop)

    粘贴用16进制工具打开图片(前面一部分):

    BM6.=…..6…(…………. …….=……………..€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€

    没有具体的数字,怎么会出现点了。。

    bmp的图片大小 3906K

    你这是16进制工具吗? 应该是: 42 4D 36 酱紫的。

    恩,刚下的专门的16进制工具,应该不会有问题的,不知道为什么出来的都是
    …(…………. …….=……………..€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€€.€€

    你帮忙推荐个好的工具。

    晕,你直接把前10个字节的ASCII码给写上来吧。
    我推荐的16进制编辑器是PSPad和XVI32,都是免费的。

    42 4D 36 E0 38 00 00 00 00 00 36 00 00 00 28 00
    00 00 00 05 00 00 D8 02 00 00 01 00 20 00 00 00
    00 00 00 E0 38 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 80 80 80 00 80 80 80 00 80 80
    80 00 80 80 80 00 80 80 80 00 80 80 80 00 80 80
    80 00 80 80 80 00 80 80 80 00 80 80 80 00 80 80
    …..
    80 00 80 80 80 00 80 80 80 00 80 80 80 00 80 80

    图片我传到纳米盘了,您看看
    图片地址:

    http://www.namipan.com/d/f0c100f85309d3be2258ca287342dd79773551e836e03800

    看来图片没有问题,是3727414。
    别研究了,是你的BITMAPFILEHEADER定义有问题,很可能是字节对齐问题或者是引用了不正确的头文件。
    右击BITMAPFILEHEADER,查找定义,看BCB打开的相关头文件是不是%BCB%\Include\wingdi.h。如果不是,应该是你的工程属性里的头文件引用顺序不对,把%BCB%\Include调在前面即可。
    如不确实是%BCB%\Include\wingdi.h,那偶也不知道是怎么回事了,你可以试试把正常的电脑上的%BCB%\Include\覆盖你的。或者最后一招,重装BCB:-(

    好的,我去试试,谢谢!

    刚把正常的电脑上的%BCB%\Include\覆盖后,可以了。
    请问下,include中的文件覆盖会不会造成我安装控件出现问题?

    Waiting4you      2008年07月17日 17点19分50秒 说:
    注意在定义的前后加#pragma pack(push,2)和#pragma pack(pop),它的作用是取消编译器的字节对齐功能。

    字节对齐是一个优化内存读写能力的功能,我想你的编译器就是错误地优化了这个结构的数据对齐,本来bfType占用两字节,接下来就是四字节的bfSize。但是你的编译器很可能在bfType和bfSize之间插入了2字节以保证所谓的字节对齐。

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ⷠ
    解决问题的方法有两个:
    1.把正常的电脑上的%BCB%\Include\覆盖不正常的电脑上的%BCB%\Include\
    2.按照您说的,BITMAPFILEHEADER的定义 前后加上 #pragma pack(push,2)和#pragma pack(pop)

    为什么别的电脑上不加上 #pragma pack(push,2)和#pragma pack(pop),也没有问题。
    我的电脑需要加上这个,就解决了问题

    看看,学习下

    BITMAPFILEHEADER的原来的定义

    #include <pshpack2.h>
    typedef struct tagBITMAPFILEHEADER {
            WORD    bfType;
            DWORD  bfSize;
            WORD    bfReserved1;
            WORD    bfReserved2;
            DWORD  bfOffBits;
    } BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;
    #include <poppack.h>

    修改后:
    #include <pshpack2.h>
    #pragma pack(push,2)
    typedef struct tagBITMAPFILEHEADER {
            WORD    bfType;
            DWORD  bfSize;
            WORD    bfReserved1;
            WORD    bfReserved2;
            DWORD  bfOffBits;
    } BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;
    #pragma pack(pop)
    #include <poppack.h>

    于是把include文件下的pshpack2.h文件比对了下
    发现打印错误的电脑上的pshpack2.h文件前后多了这两行:

    #pragma option push -b -a8 -pc -A- /*P_O_Push*/

    ……….中间相同

    #pragma option pop /*P_O_Pop*/

    poppack.h 也一样多了

    #pragma option push -b -a8 -pc -A- /*P_O_Push*/

    ……….中间相同

    #pragma option pop /*P_O_Pop*/

    马甲来顶顶,不然发不了言

    完美解决,说到底还是

    Waiting4you 大哥说的 字节对齐 问题

    把 pshpack2.h 和 poppack.h 中的头尾两行去掉,就可以了!

    谢谢 Waiting4you 大哥:),Waiting4you 大哥是好人。
    这么耐心的教我!
    再研究研究,明天来结贴!

    为什么我的电脑里%BCB%\Include\下的 pshpack2.h 和 poppack.h 头尾会多出

    #pragma option push -b -a8 -pc -A- /*P_O_Push*/
    ……
    #pragma option pop /*P_O_Pop*/

    难道是版本的问题!

    通过打sp4补丁也可以解决!

  • Filed under: C++ Builder
  • 请专家给点提示,
    例如该窗口有100条数据库的信息,是否能访问这100条信息,
    用那些API函数可以实现,具体属性和方法

    难道没有人会了吗?

    TDBGridEx是自定义的VCL组件吧,这个没有什么API支持的。我猜楼主说的应该是获取其他进程中窗体上的DBGridEx数据吧,目前可行的方法是注入到目标进程,开辟一个隐形窗口,通过自定义消息通讯,在目标进程中以对象->属性的方式读取或设置内容。也可以用全局消息钩子,用自定义消息通讯。

    几年前DelphiBBS上有一些大牛讨论过,参考:
    http://www.delphibbs.com/keylife/iblog_show.asp?xid=12219

    笔记中虽然是用Delphi操作StringGrid,但是知道了原理,用C++Builder写一个操作DBGridEx的也很容易。

    谢谢妖哥,关于这个以后有什么问题希望能指教,先结贴研究

  • Filed under: C++ Builder
  •   怎么设置才能让子窗体和提示框居中显示。因为我的子窗体和提示框都是在ocx控件中实现的,BCB调用的话,出来时没有居中显示,怎么设置才能居中显示呢?

    引用 1 楼 aniven 的回复:
    Form1->Postion = poScreenCenter;

    Postion 我全部设置过了 不行呀 还是不能居中

    第一点

    1楼的 属性名字写错了
    Form1->Postion = poScreenCenter;//错误的
    //1 楼笔误 不要打我啊。。。。

    Form1->ParentBiDiMode=true;
    Form1->Position = poScreenCenter;

    放入构造  既可

    C/C++ code
    Form1->ParentBiDiMode=true; Form1->Position = poScreenCenter;

    这个属性我设置了,可是我ocx实现的窗体 在BCB显示 还是居不了中。这个是什么问题呢?

    上代码

    C/C++ code
    GoTopChart1->AboutBox(); //ocx中代码 void CGoTopChartCtrl::AboutBox() { CDialog dlgAbout(IDD_ABOUTBOX_GOTOPCHART); dlgAbout.DoModal(); }

    up

    up

    你的是VC的代码嘛?

    ocx的话,只有你设计的时候在什么位置调用显示的时侯应该也在什么位置。

    引用 10 楼 cai5 的回复:
    ocx的话,只有你设计的时候在什么位置调用显示的时侯应该也在什么位置。

    我ocx是用vc做的。那有没有解决的方法呢?

    up

  • Filed under: C++ Builder
  • 设计时子窗体有大有小,等运行时,都变成了一样大的,这是怎么回事啊

    该回复于2008-07-12 16:35:11被版主删除

    想不通,是否你的程序加载时有自动调节大小的代码

    引用 1 楼 aniven 的回复:
    因为窗体Position属性使用了poDefault,如果要按设计时的大小改为poDefaultPosOnly

    非常感谢,你说得很对

  • Filed under: C++ Builder
  • 大家好:
        我在窗体上放置了一个IMAGE控件,在IMAGE控件上放了个位图,并做成了不规则窗体。现在我想通过双击此不规则窗体来关闭它,请问如何实现?小弟是新手,分没了,不好意思,大家帮帮忙吧!

    在IMAGE控件上双击事件中写个
    Close();就可以关闭了

    我就是这么做的,可是不行啊:(

    发送 关闭消息 WM_CLOSE

    如何发送此消息请明示,小弟是菜鸟:(

  • Filed under: C++ Builder
  • Form1->Image1->Left=10;这样后线程就挂掉了,不知怎么回事?请指教。
    我把这句放在Synchronize也是不行

    是按上面的方法做的,一执行到Synchronize(UpdateImage);
    就没动静了,程序挂掉了。

    楼上的是正规做法。

    谢谢ccrun (妖哥)的回答,我又试了下。
    void __fastcall TTestThread::UpdateImage()
    {
        Form1->Image1->Left = 10;
    }
    这样可以。
    我是这样做的
    void __fastcall TTestThread::UpdateImage(void)
    {
        Form1->Image1->Left = 10;
    }
    加了个void,这样不行,不知道什么问题?

    用于线程同步的函数是不能有任何参数的,void算是一个参数,当然,也可能VCL没有处理好这种情况

  • Filed under: C++ Builder
  • 类别

    最新

    标签

    链接


    存档