Why will MFC not load a bitmap resource in single modual (.cpp) VS PROJECT? - visual-c++

I have code that was first developed with Visual C++ Version 1.52 (working and self taught). I am now trying to convert it to a Visual Studio project. It is a single module project written with MFC. I used the 'project from existing code' option to generate the project which executes just fine but for loading bitmap resources. I tested the same relevant code (LoadBitmap and LoadImage) in MFC multi-module projects code and they work just fine. I am able to load bitmap files directly from disk. If I delete the bitmap files from the project there is 22k less size of the code. The total bitmap file size is 18k. The only error message that I get is '_WIN32_WINNT not defined. Defaulting to _WIN32_WINNT_MAXVER (see WinSDKVer.h)'. I am assuming that the default is adequate. At this point I am thinking that it is a link properties issue because of MFC, but I don't know what that might be. Any ideas? Thank you.
//header
//
class CMainWindow : public CFrameWnd
{
public:
CMainWindow();
//{{AFX_MSG( CMainWindow )
afx_msg void OnPaint();
afx_msg void OnDestroy();
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
//}}AFX_MSG
//protected:
BOOL flag;
BOOL game, turn;
CWnd tictic1, tictic2, tictic3, tictic4, tictic5, tictic6, tictic7, tictic8, tictic9;
CRect RCT;
int id, count;
CBitmap O, X;
//body
//
CMainWindow::CMainWindow()
{
LoadAccelTable("MainAccelTable");
Create(NULL, "Tic Tac Toe\0",
WS_OVERLAPPEDWINDOW, rectDefault, NULL, NULL, 0, NULL);
flag = TRUE;
id = 0;
O.LoadBitmap(IDB_BITMAP1);
X.LoadBitmap(IDB_BITMAP2);
If I transplant the relevant code into VS generated MFC documents it works. The only difference is that all of my code is original Visual C++ Version 1.52 MFC code, in a single .cpp document but all the rest of the code seems to work fine.

Uh, when I has collecting observations for this query, I deleted the two relevant bitmap files from the resources in order the report the difference in file size. After I added them back in, the functions then work properly. I think that what I had originally done was when first importing the new resources, I tried selecting the two as a group and when they displayed right, in the resource file, I assumed that it had worked. It apparently didn't. Duh!
Uh, development; after cleaning up my code, I rebuilt it and it wouldn't load bitmap resources. I deleted the resources then installed them again and the program has worked since. So you tell me. I think that it's serendipitous. Duh!

Related

ReSharper - Document Saved Event For Inactive File in Visual Studio

I’ve set up my own source control plug-in for Visual Studio.
It’s registered with visual studio and can be selected from the list of Source Control plug-ins.
I’ve got no issues with files that are modified from with in Visual Studio as I’m using to catch the event before save:
IVsRunningDocTableEvents3
If the file isn’t loaded as an active document in Visual Studio, I’m having problems detecting that it is about to be edited so I can check it out of Source Control.
I’ve tried using the ReSharper event – DocumentManagerOperations suggested here:
https://resharper-support.jetbrains.com/hc/en-us/community/posts/205991489-Document-Saved-Event
I’m having issues detecting if these types of files need checked out:
.DotSettings. – When saving the ReSharper options settings
csproj – When adding Nuget Packages with ReSharper.
.cs when editing files that are not opened in VS with ReSharper, i.e.
fix naming in project.
Is there an event that’s triggered when a file is edited but not loaded?
Thank you!
I used the interface:
IVsQueryEditQuerySave2
More information here:
https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.shell.interop.ivsqueryeditquerysave2?view=visualstudiosdk-2017
And made use of:
public int QueryEditFiles(uint rgfQueryEdit, int cFiles, string[] rgpszMkDocuments, uint[] rgrgf,
VSQEQS_FILE_ATTRIBUTE_DATA[] rgFileInfo, out uint pfEditVerdict, out uint prgfMoreInfo)
And:
public int QuerySaveFiles(uint rgfQuerySave, int cFiles, string[] rgpszMkDocuments, uint[] rgrgf,
VSQEQS_FILE_ATTRIBUTE_DATA[] rgFileInfo, out uint pdwQsResult)
something like this:
if (rgfQueryEdit != (uint)tagVSQueryEditFlags.QEF_ReportOnly)
{
if (rgpszMkDocuments != null)
{
foreach (var doc in rgpszMkDocuments)
{
//Do Something
Hope that helps you out.

Why cannot I use CString as return types or parameters in a MFC DLL made for windows CE?

I have got a library which was made for a desktop windows project. It is done in MFC VC++ by somebody else, and it works correctly. I will use one particular function from the library as an example for explaining the situation.
The example function goes like this:
CString GetFulPath(); // .h file
In the cpp file,
CString CwFolderBrowser::GetFullPath()
{
CString path;
if(this->M_pIDLIST!=NULL)
{
LPTSTR fullPath=path.GetBuffer(MAX_PATH);
::SHGetPathFromIDList(this->M_pIDLIST, fullPath); //ITEMIDLISTからパスを得る
path.ReleaseBuffer();
}
return path;
}
Now, I can include this library in my project and do something like:
CwFolderBrowser cFolderBrowser;
if(cFolderBrowser.ShowDialog() == TRUE)
cPath = cFolderBrowser.GetFullPath();
This will show a folder browser dialog and let me choose a folder. It works fine on desktop windows.
Currently, I am working on Windows CE device. We have converted the library for use with Windows CE by removing unsupported functions and stuff. The library compiles and builds correctly without errors.
Next, I create an MFC Smart Device project, include the converted library, its h file and lib files and set the proper directories for dlls. The project builds fine. I can #include the library's h file properly too.
The problem arises as soon as I call the GetFullPath function:
cPath = cFolderBrowser.GetFullPath();
It gives me an unresolved external link error! The Intellisense does show this function in its list and I can choose it and everything. But in vain.
Strangely, If I modify the library and change GetFullPath()'s signature as below,
LPCTSTR GetFulPath(); // .h file LPCTSTR instead of CString
In the cpp file,
LPCTSTR CwFolderBrowser::GetFullPath() // Return type changed to LPCTSTR
{ // instead of CString
... // Body modified accordingly
}
then, the unresolved external Link error disappears and it works!
I am stumped about this strange behaviour, because, I can use CString normally in the MFC Smart Device project and there are no errors. The link error shows up only when I try to call functions from the library (and other such libraries) dll. At the same time, BOOL, int etc. seems to have no problems as function return types.
Ofcourse, I can go through each library and change every instanceof a CString return to LPCTSTR, but that would be a very big change. I would like to know why CString works fine in project as well as dll when on desktop, while, on Win CE, it works in the project but not i the DLL (At the same time, the DLL itself compiles fine without errors wether it uses CString or LPCTSTR!).
So, basically, I would like to keep the function CString if possible, and would like to know the reason why this happens. The exact same error also happenes in other libraries too.
Any help is appreciated. Thank you.
UPDATE:
I saw a page on ATL & MFC 7.0 which said about using the /Zc:wchat_t option. I have checked the Dll project as well as my application. Both use the same option of 'Treat wchar_t as Built-in type' as Yes. So, that option matches up.
Further, as I mentioned above, changing the function return to LPCTSTR works. The error disappears. Everything is going fine until I convert the returned LPCTSTR back to CString. The CString turns out as empty/Null. This happens both inside the dll code itself, as well as in my application code too.
UPDATE2:
Thanks to Michael and Cody, I changed the function to LPCTSTR and made sure that the values were not going out of scope before I could use them like they suggested. Now the empty/Null problem is solved and I can get the path values properly.
The problem that remains is that I have to convert all the CString functions to LPCTSTR, which is not exactly feasible. I would like to keep the functions as CString.
This is a classic problem and has been asked often here on SO.
This cannot work:
LPCTSTR CwFolderBrowser::GetFullPath()
{
CString path;
if(this->M_pIDLIST!=NULL)
{
LPTSTR fullPath=path.GetBuffer(MAX_PATH);
::SHGetPathFromIDList(this->M_pIDLIST, fullPath);
path.ReleaseBuffer();
}
return (LPCTSTR)path; // << here you return a pointer to the zero
// terminated string in the path object,
} // but path will be deleted as soon as it goes
// out of scope
Maybe in some cases the function appears to work because the memory of the deleted CString object has not yet been overwritten.
You should do this (no error treatment here for simplicity):
LPCTSTR CwFolderBrowser::GetFullPath(TCHAR *pathbuffer)
{
if(this->M_pIDLIST!=NULL)
{
::SHGetPathFromIDList(this->M_pIDLIST, pathbuffer);
}
return (LPCTSTR)pathbuffer;
}
...
// call like this
TCHAR pathbuffer[MAX_PATH];
GetFullPath(pathbuffer);

MFC LoadString fails when attempting to load a string from afxres.rc

When my program attempts to generate an AFX_IDP_PARSE_REAL error for the user, it fails to load the string that is stored in the afxres.rc file. I found this question already, however it was solved because the reference to afxres.rc was accidentally deleted from the program.rc file. That is not the case for me. My program.rc file includes the exact code listed in the answer to include the afxres.rc file.
In debug mode, it breaks on the ASSERT below.
int AFXAPI AfxMessageBox(UINT nIDPrompt, UINT nType, UINT nIDHelp)
{
CString string;
if (!string.LoadString(nIDPrompt))
{
TRACE(traceAppMsg, 0, "Error: failed to load message box prompt string 0x%04x.\n", nIDPrompt);
ASSERT(FALSE);
}
if (nIDHelp == (UINT)-1)
nIDHelp = nIDPrompt;
return AfxMessageBox(string, nType, nIDHelp);
}
When I am actually running the application via the .exe, it simply generates an empty warning box since the AFX_IDP_PARSE_REAL string is not loaded; this goes for any string in the afxres.rc.
What could cause the application to not load the string from the afxres.rc?
Just letting you know that it is not enough to include the afxres.rc file normally, the way you include header files into cpp/h files. You actually need to include it twice. If you create a brand new MFC project and check the code of an rc file (using "View Code" option) you would notice that there is a normal include:
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
and there is a TEXTINCLUDE section inside the rc file:
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
You need to make sure you do the same thing in your project. Alternatively, you can use a "Resource Includes" wizard that is available via right click on the Resource View that allows editing the both sections via the dialog box:

T4 template shadow copy does not work

I'm using VS2012 and T4 templates and assemblies are supposed to be shadow copied, meaning that you can reference an assembly in a template and then recompile that assembly. But this simply doesn't work for me. When I try it, when I try to rebuild the assembly, I get errors like:
Unable to copy file "obj\Debug\xxx.dll" to "..\bin\xxx.dll".
The process cannot access the file '..\bin\xxx.dll' because it is being used by another process.
The only way around it is to restart Visual Studio, and this is so tedious that I'm ready to abandon T4 entirely. What could I be doing wrong?
So this isn't really an answer yet but hopefully we get there
Test ran the following in VS2013 (I realize you run VS2012)
<## assembly name = "$(SolutionDir)\TestProj\bin\Debug\TestProj.dll"#>
<## import namespace = "TestProj"#>
namespace ConsoleApplication1
{
class <#=Testing.Name#>
{
}
}
The TestProj contains the Testing class
namespace TestProj
{
public static class Testing
{
public static string Name
{
get { return "Tester" ;}
}
}
}
This did work very well in VS2013 and as far as I remember this worked in VS2012 as well.I will try to install VS2012 on one of my machines but do you mind testing this simple sample on your installation to validate it's not something in your solution that holds the dll?
In case you are interested in the project file you can find it here:
https://github.com/mrange/CodeStack/tree/master/q21118821
I work around similar issue. T4 design time template is processed in different App domain under the same process of visual studio. When rebuild the solution Visual Studio tries to replace the referenced DLL, and it cannot replace it because it is still in use.
I work around this issue by deleting the AppDomain in which T4 template is processed. See msdn

How to use a pre-compiled .so file in another android app?

I wonder why there is no proper answer to this question, I searched for couple of hours but no good answer.
So, we work on a team in which my friend wrote a C library and compiled it as a .so file (it's called ttplib.so)(assume I don't have access to it's C code). Now I have to use that .so file in my android application. But I don't know how to load the library and how to use its methods. I have good documentation of it.
That would be great if you can tell me how to create the Android.mk file too.
Do I have to use dlopen?
Put ttplib.so in the new project's libs/armeabi or libs/armeabi-v7a folder depending what it was compiled with.
Somewhere in your new app (before interacting with the library) add this line of code
System.loadLibrary( "ttplib" );
Now that it's loaded in memory, you'll need to interact with it using JNI. You'll have to go back to the C code to export some JNI functions:
JNIEXPORT jint JNICALL Java_com_example_package_MyClass_methodName( JNIEnv* env, jobject jthis, jfloat value )
{
return 5;
}
Then you'll need to add ClassName.java in your new project:
package com.example.package;
public class MyClass
{
private native int methodName( float value );
private void someJavaMethod()
{
int i = methodName( 65.33f );
}
}
That's it, in a nutshell.

Resources