print message to debug output window (VS)

本文介绍了一系列在Visual Studio中进行高效调试的方法和技巧,包括如何利用输出窗口打印调试信息、使用自定义宏来添加编译时提醒、硬编码断点设置、跟踪GDI资源泄漏等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Some times we could want to print the debug messages to a window (console or windows) or a file, we debug our programms with these information. There's a better way to debug programm, print the message to output window if you use VS, and you can double click the message to locate the source codes. To achive this, you only need to:

1. sprintf the message to format as: __FILE__(__LINE__):message string

2. Invoke OutputDebugString() to print the message to ouput window.

 

else, you should want to print some messages to output window when compiling, yes you only need to:

1. format the message string

#define Stringize( L ) #L
#define MakeString( M, L ) M(L)
#define $Line MakeString(Stringize, __LINE__)
#define Reminder(_s_) __FILE__"("$Line"):"_s_

 

2. output

#pragma message(Reminder("aabbccddeeff"))

 

 


 

Other useful tips for VS (转)

Microsoft Visual C++ Tips and Tricks
http://www.highprogrammer.com/alan/windev/visualstudio.html   by Alan De Smet

If you're stuck using Microsoft Visual C++, these tips may help make the experience more pleasant. I've been collecting these little tidbits for a while, and decided to collect them in one spot. I've chosen to collect them here because I can't think of a better spot.

First thing, get yourself a copy of Workspace Whiz. Workspace Whiz gives you a nice GUI interface to Exhuberant CTAGS. It also gives you a handy button to switch between the header and source files. It's cheap ($10), and makes life better.

Next, get yourself a copy of STLFilt. It's completely free. It significantly cleans up the garbage error messages Visual C++ generates for STL code. (It does require Perl, but every developer should have Perl installed anyway. The easiest way to get Perl for Windows is ActiveState's free ActivePerl .

Whenever I refer to the "sharedide" directory, you'll need to change it to the appropriate directory. In Visual C++ 5, it's actually called "sharedide" under the directory where you installed VC. In Visual C++ 6, it's in the "Common/MSDev98" directory under the directory where you installed VC.

Show compile duration
Simply add '/Y3' to the command line of VC (In the short cut). You'll now get reports on how long a compile took in your Build window.

Update 2003-01-10: I haven't had a chance to use Visual Studio .NET yet, but I'm told that you can set this option with a switch under Options > Projects > Build.

Teach VC to intelligently expand classes/structs in debugger
Isn't it neat how VC's debugger knows how to intelligently expand CStrings, CPoints, POINTS, and alot of other stuff? Well, you can teach it to handle your own structs and classes. Just edit autoexp.dat in sharedide/bin (in the directory where Visual Studio is installed.) The format of that file is fairly complicated, so I suggest just copying the examples already in the file.
Add user defined keywords for syntax highlighting
Why can you set a color for user defined keywords in Tools > Options > Format? Where do you set the keywords? Easy, just create usertype.dat in the sharedide/bin directory that Visual Studio is installed in. Put your keywords in that file, one per line.
Custom Tip of the Day
Any files with the extension ".tip" in the sharedide/bin/ide directory where Visual Studio is installed will be read. You can delete the .tip files Microsoft provides and add your own. You might want to take a look at Microsoft's files to see the format. I personally suggest filling the .tip file with quotes, news, or something more useful and entertaining that the TotDs.
How to use .cc file extensions for C++
Make the following modifications to the registry: HKEY_CURRENT_USER/Software/Microsoft/DevStudio/6.0/Text Editor/Tabs/Language Settings/C/C++ FileExtensions=cpp;cxx;c;h;hxx;hpp;inl;tlh;tli;rc;rc2;cc;cp HKEY_USERS/S-1-5-21-1219703950-274334628-1532313055-1335/Software/Microsoft/DevStudio/6.0/Build System/Components/Platforms/Win32 (x86)/Tools/32-bit C/C++ Compiler for 80x86 Input_Spec=*.c;*.cpp;*.cxx,*.cc,*.cp HKEY_USERS/S-1-5-21-1219703950-274334628-1532313055-1335/Software/Microsoft/DevStudio/6.0/Build System/Components/Tools/ Input_Spec=*.c;*.cpp;*.cxx;*.cc;*.cp

Add the flag "/Tp" to the compiler settings for the project.

Removing the "docking" capability from the menus
In Tools > Options..., in the Workspace tab, turn on "Use screen reader compatible menus". Your menus will lose the gripper (the double line on the left edge indicating dockability), and will stay nailed down like they should. Unfortunately this also removes the icons from the menus.

Useful build messages
The following macros make it easy to add reminders which are displayed when code is compiled. You can double click on a reminder in the Output Window and jump to the line. Useful for marking TODOs. (Originally from Windows Developer Journal, 1997?) // Statements like: // #pragma message(Reminder "Fix this problem!") // Which will cause messages like: // C:/Source/Project/main.cpp(47): Reminder: Fix this problem! // to show up during compiles. Note that you can NOT use the // words "error" or "warning" in your reminders, since it will // make the IDE think it should abort execution. You can double // click on these messages and jump to the line in question. #define Stringize( L ) #L #define MakeString( M, L ) M(L) #define $Line / MakeString( Stringize, __LINE__ ) #define Reminder / __FILE__ "(" $Line ") : Reminder: " < type="text/javascript">

Once defined, use like so:

#pragma message(Reminder "Fix this problem!")
This will create output like:

C:/Source/Project/main.cpp(47): Reminder: Fix this problem!
Hard code a debugger breakpoint
If you need to insert a hard breakpoint in your code (perhaps because you need to attach to a process), simply add the following line to your code.

__asm int 3;

Tracking GDI resource leaks
Plenty of tools exist to help track down memory leaks. You've got the debug heap, Rational Purify for Windows, HeapAgent, and other tools. But there aren't any good tools to help track GDI resource leaks. A resource leak can crash the system under Windows 95 or Windows 98, and can ruin performance on any Windows operating system.

The article "Resource Leaks: Detecting, Locating, and Repairing Your Leaky GDI Code" is the only real help I've found. In particular, the article includes a program that tracks current globally allocated resources under Windows 95 or Windows 98. You can track what resources were created between a start and stop points, and display what those resources are. Check the article for the download ( Leaks.exe).

Update 2003-01-10: The very friendly people at Compuware have pointed out that BoundsChecker will detect GDI resource leaks. At the moment I'm doing Unix development work, so I haven't had a chance to test it myself, but if you're fighting GDI leaks, it might be worth checking out. At the moment it appears to carry a $695 price tag. They offer a trial period. (Regrettably of the "give us your contact info and we'll contact you about a trial" type.) Check this page form information on "Funny" Memory Values. In particular:

If you're using the debug heap, memory is initialized and cleared with special values. Typically MFC automatically adds something like the following to your .cpp files to enable it:

#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endifYou can find information on using the debug heap here. Microsoft defines some of the magic values here.

While using the debug heap, you'll see the values: Value Usage
0xCDCDCDCD Allocated in heap, but not initialized
0xDDDDDDDD Released heap memory.
0xFDFDFDFD "NoMansLand" fences automatically placed at boundary of heap memory. Should never be overwritten. If you do overwrite one, you're probably walking off the end of an array. < type="text/javascript"> 
0xCCCCCCCC Allocated on stack, but not initialized


Watch Values
The watch window has a number of undocumented or minimally documented features that make it even more useful.

Display GetLastError's value and message
You can display the value GetLastError() will return by putting "@err" in your watch window. You can see the error message associated with that value by putting "@err,hr" in your watch window. If you've placed an HRESULT in a variable, adding " ,hr" to the variable name in the watch window will display the associated text.

Display pointer as an array
If you expand a pointer and you only get a single item, just add ",n" to the entry in the watch window where n is the number of elements to expand. For example, if you have a foo * pFoo pointing to an array of ten elements, put pFoo,10 in your watch window to see all of the element. This can be useful to view parts of a large array. If pFoo points to an array of 5,000 elements, you might use (pFoo + 2000),10 to see elements 2000 through 2009.

Debug checked casts
If you want maximum safety, you should always use dynamic_cast. However, if you feel you must optimize away those costs, use this version of checked_cast. It will ASSERT on a bad cast in Debug builds, but not do the slightly more expensive dynamic_cast in Release builds. // checked_cast - Uses fast static_cast in Release build, // but checks cast with an ASSERT in Debug. // // Typical usage: // class Foo { /* ... */ }; // class Bar : public Foo { /* ... */ }; // Foo * pFoo = new Bar; // Bar * pBar = checked_cast(pFoo); template TypeTo checked_cast(TypeFrom p) { ASSERT(dynamic_cast(p)); return static_cast(p); } < type="text/javascript">

Don't use SourceSafe
SourceSafe is problematic revision control system. The integration with Visual Studio is not worth the trouble. There are better solutions available. I've written a page with specific details on why Visual SourceSafe is a bad choice.


--------------------------------------------------------------------------------

Unverified
These are notes taken by a David Carley from a video of a talk given by a Microsoft Visual Studio developer. Unfortunately the original video is no longer available (or at least hidden). I haven't verified most of these.

Avoiding Stepping Into Things
It's often useful to avoid stepping into some common code like constructors or overloaded operators. autoexp.dat provides this capability. Add a section called "[ExecutionControl]". Add keys where the key is the function name and the value is " NoStepInto". You can specify an asterisk (*) as a wildcard as the first set of colons for a namespace or class.

autoexp.dat is only read on Visual Studio's start up.

To ignore the function myfunctionname, and all calls to the class CFoo: [ExecutionControl] myfunctionname=NoStepInto CFoo::*=NoStepInto

To ignore construction and assignment of MFC CStrings: (Notice the extra = in CString::operator=.) [ExecutionControl] CString::CString=NoStepInto CString::operator==NoStepInto

To ignore all ATL calls: [ExecutionControl] ATL::*=NoStepInto

Function Evaluation
Call program code from debugger Use quickwatch window, not watch window. e.g. DumpInfo (pFoo) Great for debug data Use OutputDebugString or printf Limitations 20 seconds max. Terminate on exception. Only one thread
Multi-Threaded Debugging
Current Thread ID: NT4: dw @tib+24 (thread information block) Win9x: FS register is unique per thread You can use this to set a break point to only fire on a given thread < type="text/javascript">
Naming Threads
Use "SetThreadName". The name is limited to 9 characters. SetThreadName fires an exception, which the debugger will catch and use to name the thread. The name will appears in Debug > Threads dialog. #define MS_VC_EXCEPTION 0x406d1388 typedef struct tagTHREADNAME_INFO { DWORD dwType; // must be 0x1000 LPCSTR szName; // pointer to name (in same addr space) DWORD dwThreadID; // thread ID (-1 caller thread) DWORD dwFlags; // reserved for future use, most be zero } THREADNAME_INFO; void SetThreadName(DWORD dwThreadID, LPCTSTR szThreadName) { THREADNAME_INFO info; info.dwType = 0x1000; info.szName = szThreadName; info.dwThreadID = dwThreadID; info.dwFlags = 0; __try { RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(DWORD), (DWORD *)&info); } except (EXCEPTION_CONTINUE_EXECUTION) { } }

Win32 Exceptions
If unhandled, kills app Debug > Exceptions dialog Stop Always or Stop if not Handled. Debugger sees exceptions before app, has control Stop Always lets you see where thrown Then, step, see where caught. Can add new exceptions watch output window Decoding C++ Exceptions Install ntdll.dbg to winnt/symbols/dll Set "Microsoft C++ Exception" to Stop Always
Breakpoints in System DLLs
System DLLs Windows NT only Can't just use the function name. Need the dll name too Determine DLL From Help or, grep in lib/win32api.csv Determinte the exact, unmangled name Set BP on {,,dllname}Function <=- special syntax Find true function name. Use dumpbin May need to enable "Load COFF & Exports" in 6.0
Breakpoint on certain argument values
Set breakpoint < type="text/javascript">
Determine stack offset to argument (see disassembly window)
Set condition e.g. dw esp+0x8 == 0xFFFFFFFF
Data Breakpoints
Data breakpoints are very powerful, but suffers from a confusing interface. Avoid entering "emulation" mode if possible, it's very slow.

It's often useful to break on an address: "*(long*)0x1234ABCD, length = 1".

The debugger can only support 4 hardware data breakpoints. If you use expressions (a + b), debugger uses emulation mode.

Data breakpoints only work on x86 processors, and can't catch kernel mode writes.

Data breakpoints can trigger operating system bugs. A data breakpoint set in one process might not be unset when the OS switches processes. This can cause other applications to crash. Windows 9x breaks often. Windows NT breaks less often. Reboot when it happens. Count BPs Stop on the Nth iteration To Help find N: Set BP w/ very large count (C==10000) Run until your app crashes Look at count value (X) Set count BP on C-X-1 By Name Stays put through edits (as opposed to F9, for file/line number BPs)

Memory Leaks
Docs are confusing Indexed entries talk about MFC No clear description Go to "Visual C++ Documentation/Using Visual C++/Visual C++ Programmers Guide/Debugging/Debugging Techniques.Problems and Solutions/Solving Buffer Overwrites and Memory Leaks" (6.0) Include order is important Some things redefine malloc and free, etc. Step 1, include in global header file #define _CRTDBG_MAP_ALLOC #include #include Step 2, enable checks in WinMain: // Enables tracking and reporting on shutdown. _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); _CrtSetReportMode ( _CRT_ERROR, _CRTDBG_MODE_DEBUG); It may list file/line number Will list leak number set {,, < type="text/javascript"> msvcrtd.dll}_crtBreakAlloc = n (leak number) Or, look for ASCII clues.
Memory Corruption
Heap Corruption Enable heap checking (slow) {,,msvcrtd.dll}_crtDbgFlag = 5 Data BPs may be useful
Optimized Code
It's hard Compile with /Zi Variables vanish or are wrong Use disassembly window for truth Arguments usually OK except this fastcall Just find your bugs in Debug! 8)
Casting in the debugger
Need correct type name Debugger doesn't know typedefs To find the true typename, Add variable to watch, RClick, choose properties Scoping: variable defined in current DLL, type defined in another DLL: {,,foo.dll}(CMyClass *){*}pObject pObject is local, CMyClass defined in foo.dll
Modules Window
Debug.Modules Sort by: Module name Address range Useful for finding out what module you're in Find DLL of EIP Full path Ensure you're using the correct DLL Load order (default)
Debug Works, Release Doesn't
Uninitialized variables
Often 0 used in debug builds
Unless /GZ switch is enabled
Under/Overruns of memory
use debug heap (running in debugger on NT)
Wrong calling convention (esp. GetProcAddress)
Use /GZ in compiler
Optimizer unforgiving
Overwriting locals more likely
Locals packed on stack
Locals reused
It works When I Don't use the Debugger
Windows NT uses debug heap under debugger To avoid, attach to process, rather than launching under debugger. Thread timing different PATH may be different (when lauched under MSDEV, vs shell) Call GetEnvironmentString in app to check.
Timing Code
Add two watches @clk @clk = 0 < type="text/javascript">

Watches are eval'd top to bottom. First one tells you the value of clock, second resets it. Each step will then update these values, and you can do simple profiling. Not good for assembly timing, because of debugger overhead.

Edit And Continue
Works on any builds Just use /ZI use SetNextStatement before you edit. either set it to a block before the section you want to edit, or, step out of the function, then step back in. Beware if you copy binaries Auto-relink only updates the target of the build, not the currently running copy. Your only warning is in the Output window Poor Man's Edit & Continue 0x90 = NOP Use in the disassmebly window to "comment-out" chunks of code 0x74, 0x75 == JE, JNE Use to switch the directional sense of an if statement.
Disassembly Tricks
Disambiguation dialog is annoying Choose any Ctrl+G (goto address) EIP Goes to current location.
Remote Debugging Made Easy
1. Local Machine Build Share directory to application Map back to local machine (O:) Build.Remote TCP/IP Settings.Machine Project.Settings.Debug Remote path = O:/foo/bar.exe 2. Remote machine: Install MSVCMON (you can Just install VC) (or not, if you want a very clean machine) Map share to same letter as local machine Makes finding DLLs easier Launch MSVCMON on remote Click Connect ignore all options 3. Start debugging Step & Go OK, no attach Default DLL path should be correct (VC6)
COM Debugging
Demo eax, hr Return values are in eax. If you know it's an HRESULT, you can do "eax,hr" and see the error message associated with that HRESULT. ,wm for window messages @err Use this in the watch window to display the value that GetLastError would return. @err, hr will show the msg associated with the GetLastError value. GUIDS and VARIANTs decoded New in VC < type="text/javascript"> 6.0 Make sure "Display Unicode Strings" is enabled in the options to show BSTRs etc.
Verify validity of COM object
// Verify that a pointer to a COM object is still valid // // Usage: // VERIFY_COM_INTERFACE(pFoo); // template void VERIFY_COM_INTERFACE (Q *p) { # ifdef DEBUG p->AddRef(); p->Release(); # endif }
Verify validity of a BSTR
// Verify that a BSTER really is a BSTR and is handled correctly // Warning! Fails on BSTRs which contain embedded nulls // Usage: // VERIFY_BSTR(bstrName) // #ifdef DEBUG # define VERIFY_BSTR(bstr) do { / ASSERT(SysStringLen(bstr) == wcslen(bstr)); / } while (0) #else # define VERIFY_BSTR(bstr) do {} while (0); #endif

本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/791005/archive/2006/03/06/617293.aspx

/**************************************************************************** ** ** This file is part of the LibreCAD project, a 2D CAD program ** ** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl) ** Copyright (C) 2001-2003 RibbonSoft. All rights reserved. ** ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file gpl-2.0.txt included in the ** packaging of this file. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ** ** This copyright notice MUST APPEAR in all copies of the script! ** **********************************************************************/ #include "main.h" #include <qapplication.h> #include <QSplashScreen> QSplashScreen *splash; #ifdef RS_SCRIPTING #include <qsproject.h> #endif #include "rs_fontlist.h" #include "rs_patternlist.h" #include "rs_scriptlist.h" #include "rs_settings.h" #include "rs_system.h" #include "rs_fileio.h" #include "rs_filtercxf.h" #include "rs_filterdxf.h" #include "rs_filterdxf1.h" #include "rs_filterlff.h" #include "qg_dlginitial.h" #include "qc_applicationwindow.h" #ifndef QC_SPLASH_TXTCOL # define QC_SPLASH_TXTCOL Qt::black #endif // for image mime resources from png files extern void QINITIMAGES_LIBRECAD(); #ifdef RS_SCRIPTING // extern void qInitImages_LibreCAD(); #endif #ifdef QC_BUILTIN_STYLE extern void applyBuiltinStyle(); #endif /** * Main. Creates Application window. * * Cleaning up #defines. */ int main(int argc, char** argv) { RS_DEBUG->setLevel(RS_Debug::D_WARNING); RS_DEBUG->print("param 0: %s", argv[0]); QCoreApplication::setApplicationName(XSTR(QC_APPNAME)); QCoreApplication::setApplicationVersion(XSTR(QC_VERSION)); QApplication app(argc, argv); // for image mime resources from png files // TODO: kinda dirty to call that explicitly QINITIMAGES_LIBRECAD(); #ifdef RS_SCRIPTING // qInitImages_librecad(); #endif for (int i=0; i<app.argc(); i++) { if (QString("--debug") == app.argv()[i]) { RS_DEBUG->setLevel(RS_Debug::D_DEBUGGING); } } QFileInfo prgInfo( QFile::decodeName(argv[0]) ); QString prgDir(prgInfo.dirPath(true)); RS_SETTINGS->init(XSTR(QC_COMPANYKEY), XSTR(QC_APPKEY)); RS_SYSTEM->init(XSTR(QC_APPNAME), XSTR(QC_VERSION), XSTR(QC_APPDIR), prgDir); RS_FILEIO->registerFilter(new RS_FilterLFF()); RS_FILEIO->registerFilter(new RS_FilterCXF()); RS_FILEIO->registerFilter(new RS_FilterDXF()); RS_FILEIO->registerFilter(new RS_FilterDXF1()); // parse command line arguments that might not need a launched program: QStringList fileList = handleArgs(argc, argv); QString lang; QString langCmd; QString unit; RS_SETTINGS->beginGroup("/Defaults"); #ifndef QC_PREDEFINED_UNIT unit = RS_SETTINGS->readEntry("/Unit", "Invalid"); #else unit = RS_SETTINGS->readEntry("/Unit", QC_PREDEFINED_UNIT); #endif RS_SETTINGS->endGroup(); // show initial config dialog: if (unit=="Invalid") { RS_DEBUG->print("main: show initial config dialog.."); QG_DlgInitial di(NULL); di.setText("<font size=\"+1\"><b>Welcome to " XSTR(QC_APPNAME) "</b></font>" "<br>" "Please choose the unit you want to use for new drawings and your " "preferred language.<br>" "You can changes these settings later in the " "Options Dialog of " XSTR(QC_APPNAME) "."); QPixmap pxm(":/main/intro_librecad.png"); di.setPixmap(pxm); if (di.exec()) { RS_SETTINGS->beginGroup("/Defaults"); unit = RS_SETTINGS->readEntry("/Unit", "None"); RS_SETTINGS->endGroup(); } RS_DEBUG->print("main: show initial config dialog: OK"); } #ifdef QSPLASHSCREEN_H RS_DEBUG->print("main: splashscreen.."); QPixmap* pixmap = new QPixmap(":/main/splash_librecad.png"); # endif RS_DEBUG->print("main: init fontlist.."); RS_FONTLIST->init(); RS_DEBUG->print("main: init fontlist: OK"); RS_DEBUG->print("main: init patternlist.."); RS_PATTERNLIST->init(); RS_DEBUG->print("main: init patternlist: OK"); RS_DEBUG->print("main: init scriptlist.."); RS_SCRIPTLIST->init(); RS_DEBUG->print("main: init scriptlist: OK"); RS_DEBUG->print("main: loading translation.."); RS_SETTINGS->beginGroup("/Appearance"); #ifdef QC_PREDEFINED_LOCALE lang = RS_SETTINGS->readEntry("/Language", ""); if (lang.isEmpty()) { lang=QC_PREDEFINED_LOCALE; RS_SETTINGS->writeEntry("/Language", lang); } langCmd = RS_SETTINGS->readEntry("/LanguageCmd", ""); if (langCmd.isEmpty()) { langCmd=QC_PREDEFINED_LOCALE; RS_SETTINGS->writeEntry("/LanguageCmd", langCmd); } #else lang = RS_SETTINGS->readEntry("/Language", "en"); langCmd = RS_SETTINGS->readEntry("/LanguageCmd", "en"); #endif RS_SETTINGS->endGroup(); RS_SYSTEM->loadTranslation(lang, langCmd); RS_DEBUG->print("main: loading translation: OK"); #ifdef QSPLASHSCREEN_H splash = new QSplashScreen(*pixmap); splash->show(); splash->message(QObject::tr("Loading.."), Qt::AlignRight|Qt::AlignBottom, QC_SPLASH_TXTCOL); RS_DEBUG->print("main: splashscreen: OK"); #endif //QApplication::setStyle(new QWindowsStyle()); //QApplication::setStyle(new QPlatinumStyle()); #ifdef QC_BUILTIN_STYLE //js: RS_DEBUG->print("main: applying built in style.."); applyBuiltinStyle(); #endif RS_DEBUG->print("main: creating main window.."); QC_ApplicationWindow * appWin = new QC_ApplicationWindow(); RS_DEBUG->print("main: setting caption"); appWin->setCaption(XSTR(QC_APPNAME)); RS_DEBUG->print("main: show main window"); appWin->show(); RS_DEBUG->print("main: set focus"); appWin->setFocus(); RS_DEBUG->print("main: creating main window: OK"); #ifdef QSPLASHSCREEN_H if (splash) { RS_DEBUG->print("main: updating splash.."); splash->message(QObject::tr("Loading..."), Qt::AlignRight|Qt::AlignBottom, QC_SPLASH_TXTCOL); RS_DEBUG->print("main: processing events"); qApp->processEvents(); RS_DEBUG->print("main: updating splash: OK"); } #endif // Set LC_NUMERIC so that enetring numeric values uses . as teh decimal seperator setlocale(LC_NUMERIC, "C"); RS_DEBUG->print("main: loading files.."); bool files_loaded = false; for (QStringList::Iterator it = fileList.begin(); it != fileList.end(); ++it ) { #ifdef QSPLASHSCREEN_H if (splash) { splash->message(QObject::tr("Loading File %1..") .arg(QDir::convertSeparators(*it)), Qt::AlignRight|Qt::AlignBottom, QC_SPLASH_TXTCOL); qApp->processEvents(); } #endif appWin->slotFileOpen(*it, RS2::FormatUnknown); files_loaded = true; } RS_DEBUG->print("main: loading files: OK"); #ifdef QSPLASHSCREEN_H # ifndef QC_DELAYED_SPLASH_SCREEN if (splash) { splash->finish(appWin); delete splash; splash = 0; } # endif delete pixmap; #endif //app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit())); RS_DEBUG->print("main: app.exec()"); if (!files_loaded) { appWin->slotFileNew(); } appWin->slotRunStartScript(); int r = app.exec(); RS_DEBUG->print("main: Temporary disabled delete appWin"); // delete appWin; RS_DEBUG->print("main: finished"); return r; } /** * Handles command line arguments that might not require a GUI. * * @return list of files to load on startup. */ QStringList handleArgs(int argc, char** argv) { RS_DEBUG->print("main: handling args.."); QStringList ret; bool doexit = false; QString machine; QString input; QString output; for (int i=1; i<argc; i++) { if (QString(argv[i]).startsWith("-")==false) { QString fname = QDir::convertSeparators( QFileInfo(QFile::decodeName(argv[i])).absFilePath() ); ret.append(fname); } else if (QString(argv[i])=="--exit") { doexit = true; } } if (doexit) { exit(0); } RS_DEBUG->print("main: handling args: OK"); return ret; } 给出完整代码的注释
最新发布
07-04
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值