Perhaps if Visual Studio had a way to specify post build scripts in the .user files instead of the project file, it would be more helpful.
Agreed.
I took a look through some of the code.
In VolList.h I don't think there is a need to include <windows.h>, nor for the WIN32_LEAN_AND_MEAN macro. Neither seem to be used here. It doesn't look like it's needed in VolList.cpp either.
In VolList.cpp, in function VolList::InitializeVolSearchEntry, the index can be incremented after struct fields are set.
The method name MaxVolFileCountReached seems odd. A typical convention for functions returning bool is to use an "Is" prefix or similar on the name. This convention can be seen in the methods exported from Outpost 2. Though in this case, it's more than just a boolean method, since it actually does something, namely popping up a dialog box in case the limit is reached. This isn't clear from the name, nor the use of checking a boolean return value. As this method is only called from one place, I would recommend just inlining the code in the caller and getting rid of the method. I think that would be more clear, and cuts down if tests.
It would be nice if the DBG macro could be reduced to 1 line, though I can kind of see why it was called over 3 lines for simplicity. I also noticed the DBG macro defined in GlobalDefines.h calls OutputDebugString, but there is no declaration nor include of that method in that header file.
In op2ext.h and op2ext.cpp, for method GetGameDir_s, consider declaring bufferSize as
size_t rather than
unsigned int. I've never been a big fan of the size_t type name, but I think it would be more correct.
In op2ext.h and op2ext.cpp, method SetSerialNumber, perhaps name the parameters more descriptively, such as "major", "minor", and "patch". Note that changing parameter names in method
declarations (.h) has no impact on compatibility. They are only for documentation purposes. Changes to parameter names on the method
definition (.cpp) has only local implications.
Do we need IpDropdown.h?
In IniModuleLoader.h, was there a reason for using
std::list as opposed to
std::vector for
moduleList? It should be the same length as the
std::vector returned by GetModuleNames.
I'm uncertain if the typedefs for the module function exports make the most sense in the header file or the implementation file. Thoughts?
IniModuleLoader::CallModuleInitialization has a memory leak. Since InitMod now takes a const char* pointer, the string copy is entirely frivolous. The original string should be passed, and the copy code removed.
Does CallModuleInitialization need to be it's own method? I'm thinking once the string copy code is removed, it might make sense to just inline it. That would also feel more consistent with how the DestroyMod method is looked up.
What's the point of the return value on IniModuleLoader::UnloadModules? For that matter, what is the point of the return value on DestroyMod? This value doesn't seem very actionable.
Should LoadModuleDll be responsible for displaying the error message? It's convenient, because that's where information is available, but something about it feels a bit odd. A cleaner solution might be to format and throw an exception, and have the caller display a dialog box or otherwise handle or log the error.
Inconsistency: IniModuleLoader uses HINSTANCE, while ConsoleModuleLoader uses HMODULE.
I'm going to stop here for now. There are a few sections I didn't look at in much detail.