C++Builder 程序员博客
3 Aug
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程序中 确实是可以的,
30 Jul
按钮如何打开另外一个窗体同时关掉本窗体??
谢谢
这问题很菜对吧!
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……
收藏学习
24 Jul
Form1中有一个变量a,
如果在Form2中调用a的值应该怎么做?
把变量a弄为公共的,然后在Form2包含Form1头文件,然后Form1->a 就可以了
不过不建议这样做,最好的就是在Form1弄两个接口函数,一个get 一个set 这样比较好
本人新人,最好写上代码
已經有人回答了。如果還不懂,該溫習一下書。隨便找本 C++ 或 BCB 的書 過一遍就懂了
19 Jul
设计的一个应用程序中用了两个Form,其中第二个Form中有一个Combobox,当我显示第二个form的时候,Combobox中的内容自动变成蓝色,也就是好像自动获取了焦点。我在第二个form中的显示事件中设置其他组建获得焦点,结果仍然是那个Combobox获得焦点。这是怎么回事呢?如果让Combobox不自动获得焦点?
很好。谢谢。搞定了。
17 Jul
实现功能: 打印窗体
问题:
在我的电脑上编译后运行,打印出错,错误请看下面代码。
在其他电脑上编译后运行,打印正常。
在其他电脑上不编译直接运行我的程序,打印出错。
(公司的电脑都测试了下,几台正常,几台出错)
代码如下:
Unit1.h
//————————————————————————— #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
//————————————————————————— #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 ¦ ¦ (dwBytesRead != dwFileSize)
¦ ¦ (pbmfh->bfType != * (WORD *) "BM")
¦ ¦ (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)再试试。
可以用微软的虚拟打印机调试的
不知道为什么 我的电脑上 :
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补丁也可以解决!
16 Jul
请专家给点提示,
例如该窗口有100条数据库的信息,是否能访问这100条信息,
用那些API函数可以实现,具体属性和方法
难道没有人会了吗?
TDBGridEx是自定义的VCL组件吧,这个没有什么API支持的。我猜楼主说的应该是获取其他进程中窗体上的DBGridEx数据吧,目前可行的方法是注入到目标进程,开辟一个隐形窗口,通过自定义消息通讯,在目标进程中以对象->属性的方式读取或设置内容。也可以用全局消息钩子,用自定义消息通讯。
几年前DelphiBBS上有一些大牛讨论过,参考:
http://www.delphibbs.com/keylife/iblog_show.asp?xid=12219
笔记中虽然是用Delphi操作StringGrid,但是知道了原理,用C++Builder写一个操作DBGridEx的也很容易。
谢谢妖哥,关于这个以后有什么问题希望能指教,先结贴研究
14 Jul
怎么设置才能让子窗体和提示框居中显示。因为我的子窗体和提示框都是在ocx控件中实现的,BCB调用的话,出来时没有居中显示,怎么设置才能居中显示呢?
第一点
1楼的 属性名字写错了
Form1->Postion = poScreenCenter;//错误的
//1 楼笔误 不要打我啊。。。。
Form1->ParentBiDiMode=true;
Form1->Position = poScreenCenter;
放入构造 既可
Form1->ParentBiDiMode=true; Form1->Position = poScreenCenter;
这个属性我设置了,可是我ocx实现的窗体 在BCB显示 还是居不了中。这个是什么问题呢?
上代码
GoTopChart1->AboutBox(); //ocx中代码 void CGoTopChartCtrl::AboutBox() { CDialog dlgAbout(IDD_ABOUTBOX_GOTOPCHART); dlgAbout.DoModal(); }
up
up
你的是VC的代码嘛?
ocx的话,只有你设计的时候在什么位置调用显示的时侯应该也在什么位置。
up
13 Jul
设计时子窗体有大有小,等运行时,都变成了一样大的,这是怎么回事啊
该回复于2008-07-12 16:35:11被版主删除
想不通,是否你的程序加载时有自动调节大小的代码
12 Jul
大家好:
我在窗体上放置了一个IMAGE控件,在IMAGE控件上放了个位图,并做成了不规则窗体。现在我想通过双击此不规则窗体来关闭它,请问如何实现?小弟是新手,分没了,不好意思,大家帮帮忙吧!
在IMAGE控件上双击事件中写个
Close();就可以关闭了
我就是这么做的,可是不行啊:(
发送 关闭消息 WM_CLOSE
如何发送此消息请明示,小弟是菜鸟:(
3 Jul
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没有处理好这种情况