MFC data exchange validation - c++

We're using MFC data exchange to validate some data and we're having some problems. We're using the DDV_MinMaxFloat call to ensure that edit boxes in various parts of the application contain floating point numbers within a specified range. When using this validation if a value is entered out of range a dialog is automatically displayed to the user indicating that the value must lie within the range specified. This has been working correctly whilst running the application in debug however when building a release we are getting problems. The validation is still performed in release mode however the message box displayed to the user is blank.
I've tried the usual forcing a rebuild, deleting old resource files and deleting precompiled header files but this continues to happen in release mode. Has anyone come across this before? Are there any obvious things to look for?
I should also add that this application is over 10 years old, so obviously has been working correctly before. Somehow something has gone wrong in the last few weeks to cause this.

Those messages will come from MFC's resource strings. There might be some conflict with your own resources. Check to make sure your resources adhere to Microsoft's guidelines TN020: ID Naming and Numbering Conventions.
Pay particular attention to this bit:
MFC's internal framework implementations reserve two ranges: 0x7000
through 0x7FFF and 0xE000 through 0xEFFF.

Somehow something has gone wrong in the last few weeks to cause this.
Since your application worked fine a few weeks ago, it should be easy: check out the last working version from your revision control system and compare it with the current version. Or try to narrow it down to the first revision which does not work any more.

Check with Spy++ if there are controls on the message box that is displayed and if the text on them is blank, or if there's no controls on them at all. If the text is empty, you'll have to check the resources or the way the messagebox is called/created. Otherwise it may be something like resource being set incorrectly and the message assuming it can read its resource strings from ::AfxGetResourceHandle(). Note that this is a very easy error to make - it's a global handle that can be changed everywhere (including in dll's that you have no control over) so changes in remote parts of the code that at first sight seem unrelated may trigger it.

Related

Setting the label for a Windows networking mapping

Is it possible to give a network drive mapping (as created with the WNetAddConnection functions or "Map network drive..." GUI) a label other than the default "<Target Name> (<Target Path>) (<Drive Letter>:)" one?
I tried giving SetVolumeLabel a go but this always fails, and I see nothing in the WNet API's to specficy the display label.
This isn't a 100% solution but it's more of an answer than a comment...
If you rename a mapped network drive the the GUI (by right clicking on it and going to 'Rename') it adds a value to the registry. Reading round on various sites (notably this one) it looks like Windows may sporadically delete this value by itself, so this may not be a permanent solution...
I have just manually done it through regedit and it worked in the GUI, so I see no reason why it shouldn't work programmatically as well
Add a string value called _LabelFromReg with a value of whatever you want the label to be to the registry key
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\MountPoints2\##<server-name>#<share-name>
This key should already exist if you have already created the share.
Apparently (see the link above) you then need to make that key read-only to prevent the OS from changing it back at will - I don't know how you would do that programmatically but i'm sure it can be done.
I know there are huge gaps in this answer, but maybe it's a poke in the right direction?

help with type of window dialog resource needed

I am writing a windows program (no mfc) and need to output a status line to the operator every few seconds or so. I tried using rich text boxes but after so many hours it seems to hang up. Does anybody have an suggestions on what I can use instead?
People mentioned that my buffers might have been exhausted. I thought I had planned for that. After I had about 1000 lines displayed I would take the first 500 and remove them using the select and cut options in rich text boxes. I still ran into the same problem.
This question appears relevant, and this one too. But they don't give any concrete recommendations for an alternative to rich text boxes.
You might try the Scintilla control (scintilla.org) which does not appear to have any hard limitations on text size. It has a permissive license. It is used by many text editors such as Notepad++, Notepad2, Code::Blocks, FlashDevelop. I haven't tried it personally but there from the documentation it looks easy to use it in a Windows API application. Of course, it might be overkill for your purposes.
If you keep appending to the text in the control every few seconds for hours then you are probably running into some memory constraint on the control or the process. I think you would have this problem with any control you choose given update frequence and how long you're running the program.
Have you considered implementing a simple circular buffer for the content of the text box? Say only keep the last hour's messages. You could maintain a separate log file for history if the operator needed to go back in time for hours.
I ended up writing my own control to do this, essentially duplicating the Output window in Visual Studio. It was a success, but it ended up being much more code than I thought it would be when I started - I insisted on features such as auto-scrolling when the cursor was on the last line, select/copy, bold text, etc. It was backed by a std::deque so I could limit the number of lines stored for the window.
Unfortunately the code belongs to a former employer so I can't share it here.

Detect when cut-ed data is being pasted in MFC COleDataSource VS2008

I need to detect when another application /window in my app does paste on my previously set data , so I can remove it from my source window. I have discovered that COleDataSource::DelaySetData theoretically does this and COleDataSource::OnSetData would get called when paste occurs, but I can not be sure. MSDN is (as usually) vague about this matter and does not clearly say one way or the other.I will be using an custom format and watever format is explorer using for cut/paste files.
So the question is how EXACTLY (not theoretically) can this be done.
I really need to remove the items from my window if and only if they are pasted somewhere else.
You're doing it all wrong. When you Cut something it's supposed to be deleted immediately, and you should provide an undo function if it needs to be restored.
The clipboard was not designed for bidirectional signalling. DelaySetData is intended for applications which are submitting large amounts of data in different formats, so that they only need to provide the format which is required by the receiver; using it to detect when a paste occurs is relying on a side effect. There are clipboard managers which might make this fail.

Scan for changed files

I'm looking for a good efficient method for scanning a directory structure for changed files in Windows XP+. Something like how git does it is exactly what I'm looking for, when running a git status it displays all modified files, all new (untracked) files and deleted files very quickly which is exactly what I would like to do.
I have a basic model up and running which performs an initial scan and stores all filenames, size, dates and attributes.
On a subsequent scan it checks if the size, attributes or date have changed and marks as a changed file.
My issue now comes in detecting moved and deleted files. Is there a tried and tested method for this sort of thing? I'm struggling to come up with a good method.
I should mention that it will eventually use ReadDirectoryChangesW to monitor files and alert the user when something changes so a full scan is really a last resort after the initial scan.
Thanks,
J
EDIT: I think I may have described the problem badly. The issue I'm facing is not so much detecting the changes - I have ReadDirectoryChangesW() using IOCP on multiple threads to detected when a change happens, the issue is more what to do with the information. For example, a moved file is reported as a delete followed by a create and a rename comes in 2 parts, old name, followed by new name. So what I'm asking is how to differentiate between the delete as part of a move and an actual delete. I'm guessing buffering the changes and processing batches would be an option but feels messy.
In native code FileSystemWatcher is replaced by ReadDirectoryChangesW. Using this properly is not simple, there is a good baseline to build off here.
I have used this code in a previous job and it worked pretty well. The Win32 API itself (and FileSystemWatcher) are prone to problems that are described in the docs and also discussed in various places online, but impact of those will depending on your use cases.
EDIT: the exact change is indicated in the FILE_NOTIFY_INFORMATION structure that you get back - adds, removals, rename data including old and new name.
I voted Liviu M. up. However, another option if you don't want to use the .NET framework for some reason, would be to use the basic Win32 API call FindFirstChangeNotification.
You can use USN journaling if you are up to it, that is pretty low level (NTFS level) stuff.
Here you can find detailed information and source code included. It is written in C# but most of it is PInvoking C/C++ functions.

MFC resource.h command/message IDs

I'm working on an MFC application, that got pretty messy over years and over different teams of developers. The resource.h file, which contains all command/message mappings grew pretty big over time, and has lots of problems (like duplicate IDs). I am not proficient with MFC, so the question might sound pretty stupid...
MSDN docs mention that Command IDs and Message IDs should not be less than WM_USER and WM_APP correspondingly. I saw that most of the command IDs in resource.h generated by Visual Studio begin around 100. Shouldn't this cause some interfering with MFC/Windows commands and messages, that overlap with the application defined IDs? For example, I have a command ID :
#define ID_MY_ID 101
and there is a windows command that has the same ID. When MC send this command to the APP, it's handled like an application defined ID_MY_ID, and the app is taking unnecessary actions. Is it a possible scenario?
Also, is there some third party tool that helps to profile the project resources?
Update 1:
New question showed up:
What is the preferred way of adding new custom commands to the application classes? As I understood, before they were added in the following way: add a command ID to the resouce.h, and then add a message map handler to the handling class.
You are mixing two things:
Message IDs. These must be larger than WM_USER. Message IDs are not defined in resource.h. It seems from your description that you are not using application private messages.
Command IDs. Your application itself must not have duplicate command IDs. The command ID values should also not interfere with the standard MFC IDs defined in afxres.h. Theses command IDs start at 0xE100, so it is unlikely that the values in resource.h. The resource compiler will generate an error for duplicate IDs in you rc file
There is probably no need for you to edit resource.h manually.
I would recommend to use the "Resource symbols" tool (right click on the resources in resource view and choose from the popup menu, I assume you are using VC++), to remove all the unused IDs from resource.h.
command messages are sent in WM_COMMAND with command id in parameter so it won't conflict other messages.
Generally, there is no need to insert or edit the identifiers in resources manually (identifiers assingned by VS automatically in a correct manner). There are some cases that require manual interference in identifiers, but you can start with assumption, that work of previous teams of developers with resources was right. So if you did not encountered a problem because of resources, keep them untouched (IMHO).
"MSDN docs mention that Command IDs and Message IDs should not be less than WM_USER and WM_APP correspondingly." - It seems you something mixed up.