Thanks, I have already looked at it but they involve a CreateProcess call. Which means an extra process. This is what I want to avoid actually.
Dimitris Vikeloudas
Posts
-
How to redirect stderr into CEdit control? -
How to redirect stderr into CEdit control?I have a lot of legacy code using fprintf(stderr, .....); I also have monitoring pane which is a CEdit control. How can I redirect stderr to output into the CEdit control? I have a look around but most of the answers involve the creation of a new process. Is any simpler way of doing it? Effectively what I 'd like to do is something like start redirection of stderr to myEditControl; fprintf(stder, ....); finish redirection of stderr Thanks :)
-
Which low-level I/O API is better? MFC or POSIXThanks a lot...That clarifies a lot the picture. I can suspect that compilers like g++ may provide their own implementation of open & read using the NtOpenFile or ZwOpenFile but from my perspective these internal functions are a no-go area. CreateFile etc are low-level enough :)
-
Which low-level I/O API is better? MFC or POSIXI am aware of the portability benefits of CRT functions. I also know that in standard C their API derives from the UNIX system calls. To my knowledge in a UNIX system usually (if not always) there isn't a lower level I/O function than open, read etc. However, I couldn't find what happens in Win32 platforms. Are the CreateFile, ReadFile the equivalent of system calls? Does this mean that CRT functions like open or read are implemented using CreateFile and ReadFile. I suspect this is the case but I couldn't find any MS documentation stating that. It would be interesting actually to see outline of implementation of open/read etc using Win32 API and see what flags do they pass etc. if of course that's the way they have been written.
-
Which low-level I/O API is better? MFC or POSIXFew years ago we ported our application low-level to MFC. Instead of using open, read, write etc. we moved to MFC specifics like CreateFile(), ReadFile & WriteFile. We also did the same for the locking functions i.e. use LockFileEx instead of fcntl. Recently we start using WRITE_THROUGH flags everywhere to force direct writing to disk rather than via O.S system cache. Whilst most customers are happy and solved few of their problems some of them still have issues that are hard to track and reproduce. Hence there is a thought to go back to POSIX I/O API but this may creates us again more problems than it solves. My question is the following: Assuming that we are targeting a Win32 platform (XP and Vista) which I/O is the better low-level I/O it terms of a) performance, b) security of the following choices? i. MFC specific functions like CreateFile, LockFileEx etc. ii. POSIX style low-level I/O API like _open(), _fcntl()using a VC++ compiler iii. POSIX style low-level I/O but this time using a late version gcc/g++ compiler. If someone has the same dillemas would be nice to hear the views. Also if someone knows any article or comparisons could you please direct me to them? Thanks.
-
Dll and global variables.That's almost exactly how I did it. It seems to work but still get a linking warning of multiple definitions. I think the problem comes from the difference between the declaration and the definition with initialisation. To be more specific my code originates from Unix. What I use to have there was File export.h
#ifndef _my_variable_decl #define _my_variable_decl extern int my_var; #endif
which was included by all the clients. However, because the variable is external I have to redeclare it in a local file in one of my libraries. The declaration & its initialisation is File globals.cpp#include int my_var = 10;
Now migrating to Win32 I transform it File export.h#ifndef _my_variable_decl #define _my_variable_decl #ifdef _WIN32 #ifdef _MY_DLL #define MY_EXTERN __declspec(dllexport) extern #else #define MY_EXTERN __declspec(dllimport) extern #endif #else #define MY_EXTERN extern #endif MY_EXTERN int my_var; #endif
and modified the initialisation as follows File globals.cpp#include #ifdef _WIN32 #define MY_GLOBAL _declspec(dllexport) #else #define MY_GLOBAL #endif MY_GLOBAL int my_var = 10;
As you said the _MY_DLL is set only when I compile the main dll part of it is globals.cpp. Other dlls include export.h. This code works and my_var behaves as a global variable inside the main dll and any other dll (note also that it is still compatible with UNIX). However, when I build the main DLL I get a warning of globals.obj : warning LNK4197: export "?my_var@@3IA" specified multiple times; using first specification which is due to the fact that _WIN32 think that the variable is declared twice (at least that's what my Visual C++ 6.0 compiler says). I tried to remove theextern
keyword in the windows part of the export.h but then it does not compile. I tried to add a__declspec(selectany)
and again I get the same warning. It is an annoying warning and nothing more so I am incline to endure it since my_var is a real global variable. I thought to reshape the code as following File export.h#ifndef _my_variable_decl #define _my_variable_decl #ifdef _WIN32 #ifdef _MY_DLL #define MY_EXTERN(_type, _var, _val) __declspec(dllexport) _type _var = _val #else #define MY_EXTERN(_type, _var, _val) __declspec(dllimport) _type _var #endif #else
-
Dll and global variables.Thanks but I think shared memory will complicate my code immencelly. I gave it a thought but then it is too much of a complication. In the worse case I 'll keep it as it is and will have to ignore the compiler warnings. After all despite the warnings the existing code seems to work (not sure though if it is by accident though).
-
Dll and global variables.Appologies for the typo in the original post. Where
__dllspec
read <code>_declspec</code>. However, I am not sure that I understand since the only thing I am building is two dlls (exes come much further down the line and they do not really know the variable). Thus, how I create the g_iYourVariable initialise in one of source files of the first dll, use it in all other sources of the same dll, export it and be able to imported (assuming using__declspec(dllimport)
) in any other dll file)? -
Dll and global variables.How do I declare initialise a global variable, exported from one dll and use it from various files? Let me be more specific. Assume that I have two libraries (i.e. dlls) in my application A & B. The A library consists of the A_1.cpp & the A_2.cpp file (among others). The B library consists of a B_1.cpp source. The requirment is that both use a global variable A_X which is stored in the A dll. In UNIX using gcc I declare the code in a common header A_X.h Thus the A_X.h looks like
extern int A_X;
Then in library A my two sources look like A_1.cpp source#include "A_X.h" /* initialise A_X variable */ int A_X = 10;
A_2.cpp source#include "A_X.h" .... code using A_X;
and in library B the source code of B_1.cpp is looking like#include "A_X.h" .... code of B_1 using A_X;
I have tried the following in windows A_X.h header :#ifdef LIB_IS_A __dllspec(dllexport) extern int A_X; #else __dllspec(dllimport) extern int A_X; #endif
and the A_1.cpp source in A dll#include "A_X.h" /* initialise A_X variable */ __dllspec(dllexport) int A_X = 10;
The rest of the sources are the same. Although the solution worked I take the following warning in Win32 when I try to build the A.dll A_1.obj : warning LNK4197: export "?A_X@@3IA" specified multiple times; using first specification How can I declare my A_X to be a global variable. I.e. delcare it in a header, use it in both A.dll and B.dll, store it in A.dll once, and be able to use it by any source that I include that header? -
debugger in visual c++Shift-F11 is technically step return which means that it will return to the caller. Sometimes the caller is not directly your source but something else in assembly (perhaps parameters etc). Also I am strongly suspect that your application is not completely build in debug mode. My hint is try not to enter into assembly (if you can) and make sure that all 600,000 are build in debug mode. If they are sometimes you should be able to see as assembly comments the source C lines. If so then try to see why the debuger cannot find the actual source file. Do you point it to them properly?
-
debugger in visual c++Well by pressing Shift-F11 returns to the caller. I found the usually this works. Another trick is to use the variables debug window. The context list box contains the stack of the functions. You can see where in the code are you in any depth. Select the level that you 're interested and put a break point immediately after the current step. Then press F5 (run into cursor) to bring you there. However, the best way is to know where not to step into. If your application is propery build in debug mode try not to step into functions that you do not recognise and especially those that they are known library functions (like printf, calloc etc.) Note that for some MFC classes/functions microsoft provides the source codeto assist you seeing the bug. You will know that by the name of the file that the debuger opens.
-
Zooming a textI can obtain the LOGFONT and I know how to handle the font that I 've created. My problem with the LOGFONT (and the CFont class) is that having the structure I do know in which fields should my zooming factor applied (I assume multiplied) to get a bigger or smaller font aesthetically pleasing. Any help on that please? I thought that another way doing that could be applying a transformation to the device context of the CEdit window (maybe using the ModifyWorldTransform to scale it?) but it does not seems to affect the text in a CEdit. Is it possible to scale a CEdit window??
-
debugger in visual c++Here is how in general a debugger workds: When you build your application in debug mode the executables and/or dlls (or other library files) contain a lot of extra information on top of the actual code. That information are like hyper links to the source C code. Imagine like saying "the following ten assembly commands are in that line of that cpp file". The debuger, in order to display you the source code, it needs the extra 'debug' information and access to the cpp source file. When the debuger cannot find the source code it displays what it runs in assembly. If you are an assembly guru you might be able to debug the application with that. The usual reasons that goes to assembly are: i. The application or parts of it are not build in debug mode. Thus, the debuger has no clue where the source is. ii. The function you step in belongs to the compiler libraries. No company will give you the source C code of them so stepping into them means you go into assembly. iii. You haven't informed your debuger where the C source code is. Perhaps that has to do with the project settings etc.
-
Zooming a textI have a CEdit control and I would like to be able to zoom the text by a floating factor (i.e 0.75 or 1.25 for 80% or 100% zoom). I manage to resize the box to shrink or expand depending on the factor. However, I cannot get a scaled text. I tried the following code
// Scale the window. XFORM xForm; xForm.eM11 = xForm.eM22 = (FLOAT)m_rZoomingFactor; xForm.eM12 = xForm.eM21 = xForm.eDx = xForm.eDy = (FLOAT)0.0; HDC hDC = this->GetWindowDC()->GetSafeHdc(); SetGraphicsMode(hDC, GM_ADVANCED); ModifyWorldTransform( hDC, &xForm, MWT_LEFTMULTIPLY );
either by calling it directly or by placing it inside the OnPaint message handler but I get no change. I also thought that I may need to change the existing font. However, I looked to CFont class and to LOGFONT structure and I haven't seen a simple way to get a font which is a zoomed version of the current font. How can I zoom a text in a CEdit control? Can I do it but somehow scaling the device context or should I change the font? How do I get a scaled version of the current font? Note that this change may happen on fly. I 'd like to be able whilst the user is editing the text to zoom in and out. Resizing the box is not a problem but zooming the text is. -
Writing Code for 64-bit windowsWindows System Programming (Third Edition) by Johnson M. Hart has some chapters about Win64. Maybe you want to have a look. In general there should not be a great difference between Win32 & Win64 apart from the obvious ones. Search for any conditional compiled code under _WIN32 directive. Consider if such code will work in Win64 and if so (most likely) add the _WIN64 directive there. Also when you are using pointer arithmetic do not hardwire the sizes but use the sizeof operator. Well, most of us do that anyway so should not be a problem. Keeping things simple is a great art
-
Inline editing: How explorer does it?I am developing diagram editor where I am trying to add an inline edit focility. The editor is a CScrollView subclass and on text areas I impose a CEdit view subclass to permit inline change of the text. I observed the following on Windows Explorer. Assume you start renaming a file. Type an invalid file name (e.g. a dublicated one)and then try to select another window. The explorer does not leave you to do that. It will prompt that the filename is invalid and then it will keep the window on top. Thus, you cannot go away with an invalid name. How does it manages to stay on top if the name is not valid? It is necessary for me to achieve that if I want to have a consistent behaviour with the explorer (i.e. to comit changes if the input focus is lost). I know that must be done upon the receival of the EN_KILLFOCUS message. I 've tried that code BOOL U_W_SCROLL_VIEW::OnCommand( WPARAM wParam, LPARAM lParam ) { if( m_pEdit->GetSafeHwnd() == (HWND) lParam ) switch(HIWORD(wParam)) { ............... case EN_KILLFOCUS: if( this->IsIconic() ) cancel_edit(); else { confirm_edit(); // This will delete the CEdit subclass if the code is invalid if( m_pEdit != (U_W_Edit *) NULL ) { this->BringWindowToTop(); this->SetActiveWindow(); m_pEdit->SetFocus(); } return TRUE; ..................... } return FALSE; }
-
CEdit: How do I track non visible edit changes?Just tried that, makes no difference. I think the parent (a CScrollView subclass) does not reflect the EN_UPDATE/EN_CHANGE message properly to the child CEdit for some reason.
-
CEdit: How do I track non visible edit changes?I have a subclass of a CEdit. I want to be able to resize the visible edit control until it reaches a preset bound and then to keep scrolling horizontaly and vertically. I wrote the following code To create the control
dwStyle = ES_LEFT | WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL; if( multiline ) { m_pEdit->setMultilineOn(); dwStyle = dwStyle | ES_AUTOVSCROLL | ES_MULTILINE | ES_WANTRETURN; } // First set the visible text bounds. Simply store them // in member variables. m_pEdit->set_bounds(maxWidth, maxHeight); // Now create the edit control window m_pEdit->Create(dwStyle, rect, this, ID_inline_edit); // Adjust the edit control window m_pEdit->SetWindowText(text.data());
The message mapping of my CEdit isBEGIN_MESSAGE_MAP(U_W_Edit, CEdit) //{{AFX_MSG_MAP(U_W_Edit) ON_WM_CTLCOLOR_REFLECT() ON_CONTROL_REFLECT(EN_UPDATE, OnEditUpdate) ON_NOTIFY_REFLECT(EN_UPDATE, OnEditUpdate) ON_WM_KEYUP() ON_WM_SIZE() ON_WM_CHAR() //}}AFX_MSG_MAP END_MESSAGE_MAP()
My resize code is simpleafx_msg void U_W_Edit::OnEditUpdate() { // Probably called before the window is created. if( !::IsWindow(this->m_hWnd) ) return; // Nothing to do. Internal flag to check for maximum sizes if( m_bMaxSizeReached ) return; int length = this->GetWindowTextLength() + 1; AB_TextBuffer text(length); GetWindowText(text.data(), length); AB_Integer width; AB_Integer height; this->get_text_extend((AB_Text) text, width, height); BOOL resize = FALSE; if( width.to_long() > m_width && width <= m_maxWidth ) { resize = TRUE; m_width = width.to_long(); } if( height.to_long() > m_height && height <= m_maxHeight ) { resize = TRUE; m_height = height.to_long(); } if( resize ) this->SetWindowPos( NULL, 0, 0, m_width, m_height, SWP_NOMOVE | SWP_NOREPOSITION | SWP_NOZORDER ); }
However, any time that I type a new character it scrolls it horizontally or vertically. It never resizes the control until it reaches the maximum sizes. I used Spy++ and realised that the EN_UPDATE message never reaches my CEdit subclass. I wonder how can I know that the stored text has changed. I tried doing it within the OnChar but it is a nightmare to filter out all characters like arrow keys etc and add in the existing text the new key. Is any simple way to track that the stored tex -
How can i detect that the system has just restarted/powered onWhat you mean by has just been powered Just is an inaccurat term. If you mean that you have an application violently terminating due to system shutdown and restart then your application should leave enough traces to recover itself. I suppose that Win32 will have an interface to give you the latest loggin time of the current user if that's help.
-
Where is the mouse??I have an application with plenty of windows. Some of them a re CView subclasses others are controls etc. My views usually track the mouse using the mouse events like the
CWnd::OnMouseMove
messages (which I have properly mapped etc). Reading the OnMouseMove help says that: 'The framework calls this member function when the mouse cursor moves. If the mouse is not captured, the WM_MOUSEMOVE message is received by the CWnd object beneath the mouse cursor; otherwise, the message goes to the window that has captured the mouse.' I would like to know at a given point where the mouse is, or actually if the recepient of the next mouse input message is the current CWnd or not (i.e. is it still beneath the cursor?). I 'd like to write code likeMyClass::OnMouseMove(....) { DoMyInitialAction(); _//an application action_ if( MouseInputStillOnMe() ) DoSomeOtherAction(....); _//another application action_ }
If myDoMyInitialAction
creates a new view it is likely that the next mouse input message will go on that one. I do not want to capture the mouse and receive any event related to it just in case that theDoMyInitialAction
does that (It's a black box. I do not know what will do). Thus is it possible to write aMouseInputStillOnMe()
query which will not post any message to my message queues but will tell me that under the current circumanstances I 'll receive the next mouse input message? I assume that I can use theCWnd *CWnd::GetCapture( )
to find if another CWnd in my thread receives the mouse events but this does not answer if my window is still the one beneath the cursor. How do I found if it is? Thanks a lot for any help.... Dimitris...more you ask, more you learn