QT中QmessageBox bug的修复

   QT3.2版本的QMessageBox有这样一个bug,就是当你传的参数足够长以至于你的屏幕不能显示的时候就会将字符串截断,剩下的字符串就无法显示了,如果本身的字符串长度已知,那就很好办了,在字符串中间加换行符呗,但是很多时候这个字符串的长度是不定的,程序中发生异常了catch后把字符串显示出来,不同的问题显示的长度就不一样。

   到QT4这个bug就被修复了,但是很多较老的软件用的还是QT3的版本,偶尔会遇到这个问。

   解决问题的方法能看出一个人处理问题的能力。解决这个问题有三个方法:1,在QMessageBox调用之前判断字符串,只解决一个位置的bug,显然不行;2,在工程中新建一个QMessageBox类,把QT库的QMessageBox宏定义到新的QMessageBox下面的方法,然后改变编译器检索函数库的顺序。这个办法能解决问题,但是很不幸,我宏定义之后还是会调用QT的函数,不知道是不是编译器的问题,后来没办法就重新定义一个QMessageBoxN类,然后批量改里面所有的函数,问题是解决了,但是扩展性太差,为以后的维护和升级带来不便3,修改QT库,重新编译QT库,肯定可以根本解决问题。

   开始看到这个问题第一反应就是用第一种方法,较长就插个换行,但是程序中所有的甬道这个函数的地方都有出项这个问题的隐患,当时直接想到的就是修改QT库,然后编译,用新的dll就可以了,但是当时因为编译3.2遇到了一些问题,半天也没编译成功,编译出来的dll总是少200多个函数,后来偷懒采取了第二种方法,其实用第二种方法就开始做民工了,工程里面有四十多个solution,就这样批量的替换了四十多次,问题是解决了,但是很不甘心。于是又去编译QT库,后来通过查找log文件,终于变过了,改就很简单了

 

  
  
1 QString QMessageBox::textJudgement( const QString & text )
2
{
3
QString textTemp(text);
4

5
int indexLongString = 0; //the index of whole string
6   int indexShortString = 0; //the index of one line
7   int maxLine = 200; //the max of one line
8   int changePoint = 100; //the point turn to a newline
9  
10 while ( textTemp.at( indexLongString)!='/0' ) {
11
indexLongString++ ;
12
indexShortString++ ;
13
if ( textTemp.at( indexLongString) == '/n' ) { //When meet char '/n'
14   indexShortString = 0; //turn to a newline
15 }
16
if ( indexShortString >= maxLine&&textTemp.at(indexLongString) == ' ' ) { //When longer than maxLine
17 indexShortString = 0; //turn to a newline at a char ' ' nearby
18 textTemp.insert( indexLongString,'/n' );
19
}
20
}
21
return textTemp;
22
}

 

 

主要在QMessageBox添加这样一个函数,来判断字符串是否过长,注意不能把一个单词分成两个。然后在这个类里面的几个QMessageBox函数前面调用这个函数,如下

 

  
  
1 int QMessageBox::question( QWidget * parent,
2
const QString& caption, const QString& text,
3
int button0, int button1, int button2 )
4
{
5
QString temp = textJudgement(text);
6
QMessageBox *mb = new QMessageBox( caption, temp, Question,
7
button0, button1, button2,
8
parent, "qt_msgbox_information" , TRUE,
9
WDestructiveClose);
10
Q_CHECK_PTR( mb );
11
return mb-> exec();
12
}

 

以前自己是很少去看源码的,但是有时候解决问题最好的办法就是看源码,改源码,而且看源码学东西更快一些。这就是开源的好处吧,如果QT不是开源的,那要解决问题就会更麻烦一些,而且大多时候很莫名其妙的冒出一个问题,不知道是哪里引起的,就像windows下经常打来一个程序上来就一句XXXXX地址不能read,然后程序就挂了,但是在linux下就不会有这个问题,而且即使出了问题你知道去哪里找。

#include "mainwindow.h" #include <QApplication> #include <windows.h> #include <wtsapi32.h> #pragma comment(lib, "Wtsapi32.lib") int main(int argc, char *argv[]) { QApplication a(argc, argv); HANDLE hToken = NULL; DWORD dwSessionId = WTSGetActiveConsoleSessionId(); if (!WTSQueryUserToken(dwSessionId, &hToken)) { QMessageBox::warning(nullptr, QStringLiteral("错误"), QStringLiteral("获取用户令牌失败!")); return -1; } HANDLE mutex = ::CreateMutex(Q_NULLPTR,true,(LPCWSTR)qApp->applicationName().toStdWString().c_str()); if(GetLastError() == ERROR_ALREADY_EXISTS) { QMessageBox waringBox(QMessageBox::Warning,QStringLiteral("警告"),QStringLiteral("程序[文本数据同步客户端]只能运行一个!")); waringBox.setButtonText(QMessageBox::Ok,QStringLiteral("确定")); waringBox.setStandardButtons(QMessageBox::Ok); waringBox.exec(); ::CloseHandle(mutex); return 0; } else { ::ReleaseMutex(mutex); } STARTUPINFO si; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); si.lpDesktop = (LPWSTR)L"winsta0\\default"; PROCESS_INFORMATION pi; ZeroMemory(&pi, sizeof(pi)); if (!CreateProcessAsUser(hToken, NULL, (LPWSTR)qApp->applicationFilePath().toStdWString().data(), NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) { QMessageBox::warning(nullptr, QStringLiteral("错误"), QStringLiteral("创建进程失败!")); CloseHandle(hToken); return -1; } CloseHandle(hToken); MainWindow w; w.show(); return a.exec(); } 以上是限制程序在windows Server2016系统多个用户界面也只能运行一个程序的QT C++代码,但是会出现以下BUG: 在还未有程序运行时,运行第一个也会直接提示 "获取用户令牌失败!",程序直接关闭,请帮我修复后给我完整代码
05-30
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值