STAR WARS in ASCII

做的很不错。但可能要先看过星战后才能看懂。
请使用telnet登陆到 towel.blinkenlights.nl
具体步骤:
1. 开始 > 运行
2. 键入cmd,找开命令窗口
3. 在命令窗口提示符下,键入 telnet towel.blinkenlights.nl
4. enjoy it!

如何在Qt程序里关闭另一个程序?

好象Qt是没有提供好的方案了。
(1)另一个程序在运行时,在某个地方写一些特殊的东西,Qt程序可以根据这些特殊的
东西进行判断该程序是否正在运行。正如qtcn群上一位同志讲的,如果该程序没有正常
退出的话,Qt程序的判断就会有问题。此外,这种solution的一个前提是Qt程序和该程
序都应该是有源码可以修改的。一个好处是绝对是cross platform的。
(2)应用独立于platform的代码。比如可以用win32 api来枚举进程,但问题是相对比较
复杂,比如在winxp和nt上的枚举相关api都不一样,在linux, mac等平台上的实现更是
不容易。
(3)msdn上给出一种相对简便的方法(http://support.microsoft.com/?kbid=153463),
也是应用win32 api。先使用findWindow,输入窗口的title,得到该程序的handler,
然后向应用postMessage向该程序发送WM_QUIT(eggheadcafe.com上有人建议用
WM_CLOSE
(http://support.microsoft.com/default.aspx?scid=kb;en-us;178893)),来关闭该
程序。缺陷,一个也是独立于平台的,另外一个,应用FindWindow,不排除有窗口
title相同的程序,这样返回的handler未必正确。

qDebug()引起的一连串free溢出

调用类似 qDebug()<"main(), db.dbConnect() ="<<db.dbConnect();
引起程序在关闭的时候,free.c内存溢出。
qDebug doc讲,在一些平台,如果输入const char* =0的时候,可能crash掉
但现在不是这个问题,
最后发现原因是 在连接的时候输入库写成 release版本了,选择对应的debug版本就ok了(QtSql4.lib->QtSqld4.lib)。
此为记!

QODBC/Qt4

调试了很长时间,总是提示说“数据源名称过长”,后来发现问题出在将connStr里的
DRIVER写成Driver了
Qt的ODBC好象对大小写敏感,所以一定要根据DSN里的原样copy过来。

bool UserSoils::connectDb()
{

//create default conn using assigned dbPath
QString connStr=QString(
"DRIVER={Microsoft dBASE Driver (*.dbf)};FIL={dBase 5.0};DBQ=%1")

.arg(dbPath());

//for access
//QString connStr=QString(
// "DRIVER={Microsoft Access Driver (*.mdb)};FIL={MS Access};DBQ=c:xxxx.mdb");
qDebug()<<"UserSoils::connectDb(), connStr ="<< connStr;
QSqlDatabase db=QSqlDatabase::addDatabase("QODBC");
db.setDatabaseName(connStr);
return db.open();
//qDebug()<<"UserSoils::connectDb(),"<<db.lastError().databaseText();

}

tt给出的重载最小化的方案

并不是很好的方法,在WindowStateChange后,实际上minimizing已经完成,
而最好的地点应该是clicking后,但未实际招执行minimizing的位置上。
重载winEvent是个不错的方法
bool event(QEvent *event)
{
if(event->type() == QEvent::WindowStateChange)
{
if (event->spontaneous() && isMinimized()) {
hide();
setWindowFlags(Qt::FramelessWindowHint);

//if you want to show the window again you need the following
//setWindowFlags(Qt::Window);
//show();

return true;
}
else
QWidget::event(event);
}
else
QWidget::event(event);

}

QMenu popup strange behavior

thanks to bubu @ qtforum.org

If you need to use all available screen, then you must look up in qmenu.cpp source file in 1273 line where is:
QRect screen = QApplication::desktop()->availableGeometry(p);
Change it to:
QRect screen = QApplication::desktop()->screenGeometry(p);
then it works like you need

Yes, it does!


TrayIcon for Qt4

把最核心的帖在这里
//credit to Jason Stubbs @ qt-interest
static HICON createIcon( const QPixmap &pm, HBITMAP &hbm )
{
 ICONINFO iconInfo;
 iconInfo.fIcon    = TRUE;
 iconInfo.hbmMask  = hbm = pm.createMaskFromColor(Qt::black).toWinHBITMAP();
 iconInfo.hbmColor = pm.toWinHBITMAP(QPixmap::PremultipliedAlpha);
 HICON icon = CreateIconIndirect( &iconInfo );
 DeleteObject(iconInfo.hbmMask);
 iconInfo.hbmMask = hbm = 0; // michalj
 return icon;
}
发现一点小问题,在如下代码里:
void TrayIcon::mouseReleaseEvent( QMouseEvent *e )
{
#ifdef Q_OS_WIN
// This is for Windows, where menus appear on mouse release
 switch ( e->button() ) {
  case Qt::RightButton:
   if ( pop ) {
    // Necessary to make keyboard focus
    // and menu closing work on Windows.
    pop->activateWindow();
    pop->exec( e->globalPos());
    pop->activateWindow();
    e->accept();
   }
   break;
   …
 }
#endif
 e->ignore();
}
pop->exec( e->globalPos()); 点在任务栏的system tray位置上,弹出来的菜单居然在任务栏上沿,而不是从鼠标点的位置上弹出。如图比较了 msn弹出菜单和这个system tray弹出菜单。看了一下QMenu源码,好象是Qt专门做的,但好象就不是那么native的感觉了。红点是鼠标点的位置。
不知道有没有人有workaround?
 

about Qtcn

Qtcn目前好象还差的比较远,缺少真正懂qt的人,可笑的这两天还在讨论c++里的class和struct,居然有这么多人搞不清楚,还固执的可笑。

F.
Wu给我写信说,qtcn他看了一下,暂时不想去,还没有形成讨论问题的氛围,有的只是几个可笑的连c/c++还搞不清楚的人在讨论幼稚的问题。将我也骂
进里面去了,我居然还在struct和class里发了好几个帖子,想使他们搞明白是怎么回事,结果被人胡搞蛮缠,成了谩骂的帖子了。只是我从来没在一个
技术论坛上会看到这种情况,不仔细研究别人给的答案,单凭自己的可怜的一点知识来判定回帖人的对错,这种后果是很可怕的,这样的风气也不可取,从个人讲妨碍个人的进步,从论坛上这种习惯会传染的。好在终于决定不再看这种帖子了。

c/c++应该是Qt的基础,c/c++没学好,学习Qt会有较大的问题。

重载最小化的默认behavior

花了整整一天的时间!真是很不容易。首先,在event()里判定 type()==QEvent::WindowStateChange是不行的,(1)WindowStateChange在最小化完成后调用,(2) hide()在event()里调用,没有预期效果,表现在hide后居然还有icon在任务栏上。其次,在WindowStateChange前,会调 用hideEvent(),但重载hideEvent仍然不成,hide后在任务栏上仍有icon。
谢谢qtforum的bubu提示,他给出的方案是:
bool testMinimize::winEvent(MSG *message, long *result)
{
if (message->message == WM_SYSCOMMAND && message->wParam == SC_MINIMIZE) {
ShowWindow(winId(), SW_HIDE); //WinAPI
(*result) = false;
d->tray->show();
return true;
}

}
然后调用 ShowWindow(winId(), SW_SHOW);显示
但有一个不足,上述hide后,不能用QMainWindow::show()回来。我在bubu的基础上改了一下,如下:
bool testMinimize::winEvent(MSG *message, long *result)
{
if (message->message == WM_SYSCOMMAND && message->wParam == SC_MINIMIZE) {
// ShowWindow(winId(), SW_HIDE); //WinAPI
hide();
(*result) = false;
d->tray->show();
return true;
}
return QMainWindow::winEvent(message, result);
}
居然发现hide在winEvent里可以用。惊喜!这样就可以用QMainWindow::show()回来了。
感谢bubu at qtforum!