C++Builder 程序员博客
5 Sep
一个程序A在运行,在定时器中设置定时,每隔5分钟提示一个信息,如何让这个提示信息窗口显示在最前面?
用了一下方法都不行,有什么办法?
BringWindowToTop(Application->Handle);
或
SetWindowPos(Application->Handle,Application->Handle,1,1,800,600,0);
或
LPDWORD lpdwProcessId;
DWORD ll = GetWindowThreadProcessId(GetForegroundWindow,NULL);
AttachThreadInput(ll,GetCurrentThreadId(),True);
SetForegroundWindow(tmp->Handle);
SetFocus();
ll = GetWindowThreadProcessId(GetForegroundWindow(),NULL);
AttachThreadInput(ll,GetCurrentThreadId(),False);
SetWindowPos(Application->Handle,HWND_TOP,1,1,800,600,SWP_SHOWWINDOW);
不行呀,执行之后只会在底下的任务栏中中闪烁,无法弹出窗口
WIN API 函数 SetForegroundWindow 把窗口拿到最前面
BOOL SetForegroundWindow
(
HWND hWnd // handle of window to bring to foreground
);
我的环境是xp,用SetForegroundWindow也不行呀
那直接用BringToFront();
ShowWindow可以试一下
ShowMessage("提示在最前面");
Form1->FormStyle=fsStayOnTop;
把你要弹出的窗体ShowModel不行嘛
SetParent试试
很简单嘛
如下:
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
Form2->Show();
Form2->BringToFront();
}
如果想显示后再隐藏,可以在Form2->BringToFront(); 后再隐藏。
该回复于2008-07-19 16:09:45被版主删除
5 Sep
写了一个函数判断子窗口是否已经打开
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的成员函数
class TForm1:public TForm { private: //user declared __published public: bool OpenForm(TFrom *WFrom) ; }
而你在写OpenForm的实现函数时,却又没有写上TForm1这个类域的名字,它只看到了声明,当然连接不到你的实现体的代码!
所以把
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; }
改成
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; }
太谢谢你了,真是高手,一眼就看出了问题
3 Sep
如题,谢谢
该回复于2008-08-03 13:19:12被版主删除
不知道楼主指的置顶是那种置顶。
一楼的办法也可以。但是不能有可能会挡住其它进程的窗口。
可以重载一下CreateParams 函数
然后设置CreateParams.WndParent = // 父窗口句柄
Form2->ParentWindow =GetDesktopWindow(); //窗口在最上层
SetWindowPos(Handle,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE ¦SWP_NOSIZE);
该回复于2008-08-04 14:27:51被版主删除
有本事就盖过微软的任务管理器窗口。微软垄断。
25 Aug
初学Borland C++,想编程实现拖曳一个Main窗口时,让另一个message窗口跟随其移动,两个窗口在拖曳过程中保持左右并排。两个窗口都是Form,且二者没有父子关系。我一开始打算在Main窗口的OnMouseDown中调整message窗的top和left,但是运行之后,发现无论鼠标如何点击,都无法进入OnMouseDown函数中。请问各位大虾,这是怎么回事呢?应该如何实现拖曳跟随呢?先行谢过各位了~~
protected:
virtual void __fastcall WndProc(Messages::TMessage &Message);
void __fastcall TForm1::WndProc(Messages::TMessage &Message)
{
TForm::WndProc(Message);
if(Message.Msg == WM_MOVING)
{
Form2->Top = Top;
Form2->Left = Left + Width;
Form2->Show();
}
}
谢谢二位的指点。现在我想加上如下的效果:拖曳Main窗口,Message 窗口跟随(已经能够很好的实现了);让Message窗口在离Main窗口足够近的地方时自动靠拢对齐。
不过按照闲云野鹤兄的方法做呢,在拖动Message窗口靠近Main窗时,容易发生Message窗闪烁的现象。我想,如果能够在标题栏上对MouseUp进行响应就好了。不知道有没有这样的方法呢?谢谢!
响应 WM_NCLBUTTONDOWN
呃 ,该是 WM_NCLBUTTONUP
23 Aug
1)
登陆框 SQL里面建立了一张表 登陆(账号,密码,权限)
登陆框里建立 两个edit分别记录帐户,密码
如何写才能 判断两者相同呢?
2)
如果我用Query 控件在DBGrid中选择显示… 怎么样才能 在一个 Edit 中输入一个数 能够更新到DBGrid中选定的那条的一个属性里呢?
比如 Edit:订购数量
DBGrid:显示的是库存信息
Query1->Close();
Query1->SQL->Clear();
Query1->SQL->Add("select * from 零件库存 where 库存量 <最低库存 and 订购量=0") ;
Query1->Open();
怎样才能更新到我所指定的行中….
1、用账户到数据库里去查询,如果返回空记录,则帐户错,否则,再比较输入的密码和数据库里的密码是否一致;
2、用DbEdit和数据原相连,修改了DbEdit的值,就能直接反映到EbGrid中,前提是数据库表要有主键、索引等。
你第一个问题,是不是说的这个意思:
Edit1->Text=Str1;
Edit2->Text=Str2;
if(Str1==Query1->FieldByName("账号")->AsString&&Str2==Query1->FieldByName("密码")->AsString)
。。。
不过在sql数据库中直接设置用户名与帐户,更方便简单,可以考虑一下。
第一个问题已经有人解了…
第二个问题这样..
update table set ziduan='"+edit->text+"' where XXXXXXXX
忘了结贴了 sorry
21 Aug
主窗口在关闭时,使用Action=caFree,在运行关闭主窗口时,出现错误如下:
Access Violation at address 400f19dd in module 'vcl60.bpl'.read of address 000002ec.
在on Close,on Destroy事件中设置Action=caFree,或者delete form;都会出现上述错误,问题在哪?如恶化正确关闭主窗口?
FormCloseQuery
CanClose = true;
自己写个析构函数
如果窗口不是动态创建的,就不用作任处理
1楼说的对,caFree是给midi窗口用的
内存出错了,看看哪里没有分配合法内存又使用了。
该回复于2008-08-08 13:11:35被版主删除
不厚道啊
晕倒,
楼上的纯属灌水,
啥问题他都这几句话,
我还以为真来解决问题的呢,
建议设置断点(F5)
然后单步调试(F8,F9)看看吧!
4 Aug
一个MDI程序,平常挺好的,现在我做了一个测试,发现问题了。
假如我在子窗口Form_FreqMon中放一个按钮,添加代码:
//—————————————————————————
void __fastcall TForm_FreqMon::Btn_JKClick(TObject *Sender)
{
for(int i=0;i <=100;i++)
{
Sleep(200);
CGauge1->Value++;
Application->ProcessMessages() ;
}
}
//—————————————————————————
如果此时直接关闭这个子窗体,就会报内存错误,并指到CGauge1->Value++;这一行,删除这行后,子窗口可以关掉了,但主窗体却不能关掉了。
在子窗体的OnClose事件中,我也写了Action=caFree;这条语句,怎么回事啊?如何解决?
3 Aug
我是直接复制帮助里面的函数,听说是用FormClose的话,这个form须是以模态出现的,而我的工程里面是用“Application->CreateForm”创建的,但是我用FormCloseQuery()也不行啊,用FormDestroy()也是不行,到底要怎样响应form右上角的那个X按钮?
谢谢!!
谢谢楼上!
我有点不明白,点BCB帮助里的“OnClose example”给出的竟是FormClose(),这不是MFC,哪来那么多OnXxxx()?
我就是在Unit1.h的TForm1类里面加上了FormClose()的声明,然后在unit1.cpp里实现了它。有错吗?
那么所谓的OnClose事件从何而来?BCB里有这个概念?
你的FormClose()是怎样声明的?BCB可以自动生成,只要F11->点Events->双击OnClose:
void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
Windows是通过消息来处理事件的,BCB只是将WM_CLOSE定义成函数罢了
VCL中组件的事件,是以On开头的,比如OnClose,OnCreate等等,在IDE中选中某个组件,对象游览器中选择Events就可以看到该组件的事件。每一个事件对应一个处理函数(当然多个控件的多个事件也可以使用同一个函数),双击某个事件右面的空处,IDE会自动生成一个函数框架(包括在Form类中的声明以及.cpp中一个空的函数定义),然后在相应的函数中填写代码即可。你可以手动的添加函数声明和定义,但是必须和组件的相应事件挂钩,否则是不会自动调用的。对于Form而言,FormClose只是IDE默认的OnClose事件的处理函数的名称。完全可以自己定义一个,如:
在.h文件中:
private: // User declarations void __fastcall MyFormClose(TObject *Sender, TCloseAction &Action);
在.cpp文件中:
void __fastcall TForm1::MyFormClose(TObject *Sender, TCloseAction &Action) { ShowMessage("自定义的FormClose事件"); }
然后,再和Form的OnClose事件挂钩:
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { OnClose = MyFormClose; }
谢谢!没想到回复的这么快!
我少了最后一步,事件挂钩。
TKS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
该回复于2008-08-02 12:36:14被版主删除
收藏
该回复于2008-08-03 13:19:11被版主删除
OnClose应该可以触发的
學習~~~~~~
31 Jul
可以实用sendmessage吗??有例子吗??谢谢
同一个进程的窗口么用指针传参数咯,要么用FindWindow,SendMessage,然后重写消息处理函数。
//消息接收处理
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(DXX_MESSAGE,TMessage,OnReceiveMessage);
END_MESSAGE_MAP(TForm);
void __fastcall TForm1::OnReceiveMessage(TMessage &Message)
void __fastcall TForm1::OnReceiveMessage(TMessage &Message)
{
AnsiString sWParam;
sWParam = (AnsiString)(char*)Message.WParam;
if(sWParam == "KKKKK")
{
//在这里输入代码
}
}
//发送消息
SendMessage(this->Handle,,sWParam,0);
获取子窗口的句柄,就可以发消息!
楼上的最简单也好控制!
如果想自己处理响应函数的话就用消息映射
3楼的正解。
该回复于2008-07-19 16:13:31被版主删除
31 Jul
我想在程序结束之后,关闭所有已经打开的资源管理器窗口,请问怎么实现啊??高手指教!!
BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam)
{
char szWinName[255]={0};
GetWindowText(hwnd,szWinName,sizeof(szWinName));
if(strstr(szWinName,lpWName)>0) //找到了相同的名字
SendMessage(hwnd,WM_CLOSE,0,0); //关闭该程序
return true;
}
//——————————————————-
//lpszWinName 窗口名
//dwType 处理类型:0,关闭窗口;1最大化,2最小化
BOOL CtrlWindow(const LPCTSTR lpszWinName, const DWORD dwType)
{
BOOL result=false;
lpWName=lpszWinName;
result=EnumWindows(EnumWindowsProc,NULL);
return result;
}
调用方式:
CtrlWindow("iexplorer",0); //窗口标题中含有 iexplorer 字符串的窗口,全部关闭