C++ shellapi - Garbage characters upon system tray bubbles - c++

So I'm making a console application in C++ with win32 and shellapi (for different reasons). Everything has gone well for most of it, although recently I've noticed some issues when calling the Shell_NotifyIcon() function.
I got this piece of code:
NOTIFYICONDATA s_data;
s_data.cbSize = sizeof(s_data);
s_data.uFlags = NIF_INFO;
s_data.dwInfoFlags = NIIF_NONE;
s_data.uTimeout = 1;
StringCchCopy(s_data.szInfo, ARRAYSIZE(s_data.szInfo), L"Test message");
Shell_NotifyIcon(NIM_ADD, &s_data);
I've included the following (relevant) header files:
#include <Windows.h>
#include <Shellapi.h>
#include <Strsafe.h>
And I get the following result: http://prntscr.com/2s5e3i
I suppose it has to do with the NOTIFYICONDATA::szInfo member, but I still can't figure out a fix to it. And considering that I've double checked with some examples online (whereas the difference has been minimal), I doubt that it's something really obvious.
Thanks in advance. I haven't been working with shell that much, so excuse me if I'm misunderstanding something major or so (or using something incorrectly). I hope I can get somewhere with this at least.
References:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb762159(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/bb773352(v=vs.85).aspx

I solved it myself, just a while after asking this strangely.
The answer is simple: You need to set NOTIFYICONDATA::szInfoTitle to something. In my case, I completely forgot about it, and expected it to use some sort of default title, but it didn't. Instead, it got replaced by garbage, making it unreadable.
To solve it, I added:
StringCchCopy(s_data.szInfoTitle, ARRAYSIZE(s_data.szInfoTitle), L"Test title");
And now everything appear neatly.

Related

Can't find COM object from C++, although Guid it's registered

First of all happy new year to everyone, hope you're doing well!
I'm working on a C++ project in which I need to call a C# DLL I created following the first answer of this post. Once I have the DLL, I need to call it from Qt, so by using dumpcpp and the .tlb file generated by regasm, I managed to get the .cpp and .h files to use my classes. Just as a reference, the namespace of the classes is Wrapper, and the main class is Device with guid {DD4A4896-C105-4C60-839B-B18C99C8FE15}.
Once I have the generated files to use the DLL, if I try to create a Wrapper:: Device instance on Qt, I get the following error:
QAxBase::setControl: requested control {dd4a4896-c105-4c60-839b-b18c99c8fe15} could not be instantiated
QAxBase::qt_metacall: Object is not initialized, or initialization failed
It doesn't give any more information, so I tried to check if the guid was stored on the system registry (I used the regasm command explained on the previously quoted post, and It said that it was successful, but you never know). Opening Registry editor and searching for the Guid revealed that it's present at: Computer\HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{DD4A4896-C105-4C60-839B-B18C99C8FE15}, which, as far as I know, is the right route for these guids, and it points to the right DLL.
I though It may be due to some kind ActiveQt problem, and as the previously quoted post explained how to use that DLL from VS C++, I decided to give it a try, using this as an another reference. I've finished with this code, which is supposed to create an instance of my Device object
#include <iostream>
#include <atlstr.h>
#import "C:\Users\javie\Documents\Wrapper\Wrapper\bin\x86\Release\netstandard2.0\Wrapper.tlb" named_guids raw_interfaces_only
inline void TESTHR(HRESULT x) { if FAILED(x) _com_issue_error(x); };
int main()
{
try
{
TESTHR(CoInitialize(0));
Wrapper::IDevicePtr devPtr = nullptr;
TESTHR(devPtr.CreateInstance("{DD4A4896-C105-4c60-839B-B18C99C8FE15}"));
}
catch (const _com_error& e)
{
CStringW out;
out.Format(L"Exception occurred. HR = %lx, error = %s", e.Error(), e.ErrorMessage());
MessageBoxW(NULL, out, L"Error", MB_OK);
}
CoUninitialize();// Uninitialize COM
std::cout << "Hello World!\n";
}
However, this doesn't work either, the createInstance method throws an exception of Class not registered and HR=80040154. Again, according to Registry editor, the class is registered, so I don't understand the error. I've also tried with devPtr.CreateInstance("Wrapper.Device"), devPtr.CreateInstance("Wrapper::Device") or `devPtr.CreateInstance("Wrapper::CLSID_Device") as the links I posted suggest, but in those cases I get another exception with HR=800401f3 and message Invalid class string.
It doesn't matter whether VS or Qt Creator are opened as administrator or not, I get the exact same error.
I have run out of ideas, and I really need to be able to use that DLL from Qt using the files generated by dumpcpp.
Does any one know what could be happening? It feels quite strange to me.
If your C++ application is 64-bit, that's the answer right there, because your C# component is 32-bit (or MSIL but registered to the 32-bit hive). In situations like these, a simple test using VBScript is always useful.
Write a simple VB Script (test.vbs)
Dim obj
Set obj = CreateObject("Wrapper.Device") ' or whatever your ProgID is
MsgBox TypeName(obj)
Now, run this macro 2 ways: with 32-bit and 64-bit versions of VBScript:
32-bit > c:\windows\SysWow64\cscript.exe test.vbs
64-bit > c:\windows\system32\cscript.exe test.vbs
This is assuming your C# component is dispatch compatible. If it's not, then it will still give you differing results that you can use to debug.
Assuming automation/IDispatch compatible, one will work and one won't if you have registered your component correctly.
Have you registered correctly? When I use regasm, I always use the the switches /tlb /codebase when registering the C# component for COM.
Ok, in case someone find the same error, I'll explain the solution I found.
The problem was that in my case, the C# class I developed depended on another 32 bits dll which was not registered on my PC. Once I registered the other dll, everything worked fine.
I don't know why VS kept telling me that the class was not registered when my class itselft was registered, it was one of its dependencies that wasn't registered.
Anyway, I discovered this thanks to Joseph's comments, so thanks a lot for your help.

Why is g_send_packet causing a crash because it's nullptr but I can't have it be anything else?

Okay, so, I'm trying to debug a DLL so that it won't crash my game when I load in but it keeps doing it for some odd reason and when I debug it, it gives me an error saying "g_send_packet was nullptr" but I can't really change what it is afaik (extremely new to this kind of stuff, only coding background is lua)
As you can see, g_send_packet is defined as an extern in globals.h, which should be fine.
extern bool* g_send_packet;
and in globals.cpp, it's defined as
bool* g_send_packet = nullptr;
But, when I inject the DLL into the game I'm running, it crashes, gives me the same line as earlier and points to this line in resolver.cpp:
if (*g_send_packet)
angle1[player->EntIndex()] = player->get_eye_angles().y;
I'm extremely confused and at this point and I'm just trying to get this to work. Any help is greatly appreciated and any extra clarification is perfectly fine with me. Thanks!

gdi+ PrivateFontCollection AddFontFile always returns status with "InvalidParameter"

every one, I'm using GDI+ to rendering text with my own typeface, but I always get a error status InvalidParameter when using member function AddFontFile(WCHAR*) of PrivateFontCollection to load my font file, here is my code:
PrivateFontCollection m_font_collection;
... // initialize window
GdiplusStartup(&gdi_token, &gdi_startup_input, NULL);
// here the result always is 2 (that specified as "InvalidParameter")
Status result = m_font_collection.AddFontFile(L"myfont.ttf");
I can't find any explanation why this error occur, does anyone knows how to fix that problem? Thanks!
ps: forgive my poor English... :)
I've solved this problem, this is a stupid question, so, forgive me... please check my answer below
My answer
OK, I've solved this problem... how stupid I am... the question is quite stupid, I defined the m_font_collection too early! It should be defined after the function GdiplusStartup has been called, only after the GDI+ has been initialized the PrivateFontCollection can load your own font files... Hope can help somebody

What has to be Glib::init()'ed in order to use Glib::wrap?

So I'm trying to make use of a GtkSourceView in C++ using GtkSourceViewmm, whose documentation and level of support give me the impression that it hasn't been very carefully looked at in a long time. But I'm always an optimist :)
I'm trying to add a SourceView using some code similar to the following:
Glib::RefPtr<gtksourceview::SourceLanguageManager> source_language_manager = gtksourceview::SourceLanguageManager::create();
Glib::RefPtr<gtksourceview::SourceLanguage> source_language = Glib::wrap(gtk_source_language_manager_guess_language(source_language_manager->gobj(), file, NULL));
Glib::RefPtr<gtksourceview::SourceBuffer> source_buffer = gtksourceview::SourceBuffer::create(source_language);
gtksourceview::SourceView* = m_source_view = new gtksourceview::SourceView(source_buffer);
m_vbox.pack_start(*m_source_view);
Unfortunately, it spits out the warning
(algoviz:4992): glibmm-WARNING **:
Failed to wrap object of type
'GtkSourceLanguage'. Hint: this error
is commonly caused by failing to call
a library init() function.
and when I look at it in a debugger, indeed the second line above (the one with the Glib::wrap()) is returning NULL. I have no idea why this is, but I tried to heed the warning by adding Glib::init() to the begining of the program, but that didn't seem to help at all either.
I've tried Google'ing around, but have been unsuccessful. Does anyone know what Glib wants me to init in order to be able to make that wrap call? Or, even better, does anyone know of any working sample code that uses GtkSourceViewmm (not just regular GtkSourceView)? I haven't been able to find any actual sample code, not even on Google Code Search.
Thanks!
It turns out, perhaps not surprisingly, that what I needed to init was:
gtksourceview::init();
After this, I ran into another problem with one of the parameter to gtksourceview::SourceLanguageManager, but this was caused by a genuine bug which I subsequently reported and was promptly fixed. So everything's working great now!
I use gtkmm. Typically you have to initialize things with something like :
_GTKMain = new Gtk::Main(0, 0, false);
Of course do not forget :
delete _GTKMain;
Check here for details :
http://library.gnome.org/devel/gtkmm/2.19/classGtk_1_1Main.html
(Sorry but the link option does not work ...)

Problem debugging C++ with an Eclipse based IDE

This is a weird question in that I'm not sure where to start looking.
First of all, I haven't done any C++ programming for the last 10 years so it could be me thats forgotten a few things. Secondly, the IDE I'm using is Eclipse based (which I've never used) and customized for Samsung bada based mobile development (it kicks off an emulator for debugging purposes)
I'm posting my code samples as images because the StackOverflow WYSIWYG editor seems to have a problem parsing C++.
[EDIT] Due to complaints I've edited my question to remove the images. Hope that helps :)
I have the following header file...
#include <FApp.h>
#include <FBase.h>
#include <FGraphics.h>
#include <FSystem.h>
#include <FMedia.h>
using namespace Osp::Media;
using namespace Osp::Graphics;
class NineAcross :
public Osp::App::Application,
public Osp::System::IScreenEventListener
{
public:
static Osp::App::Application* CreateInstance(void);
public:
NineAcross();
~NineAcross();
public:
bool OnAppInitializing(Osp::App::AppRegistry& appRegistry);
private:
Image *_problematicDecoder;
};
...and the following cpp file...
#include "NineAcross.h"
using namespace Osp::App;
using namespace Osp::Base;
using namespace Osp::System;
using namespace Osp::Graphics;
using namespace Osp::Media;
NineAcross::NineAcross()
{
}
NineAcross::~NineAcross()
{
}
Application* NineAcross::CreateInstance(void)
{
// Create the instance through the constructor.
return new NineAcross();
}
bool NineAcross::OnAppInitializing(AppRegistry& appRegistry)
{
Image *workingDecoder;
workingDecoder->Construct();
_problematicDecoder->Construct();
return true;
}
Now, in my cpp file, if I comment out the line that reads _problematicDecoder->Construct();...I'm able to set a breakpoint and happily step over the call to Constuct() on workingDecoder. However, as soon as I uncomment the line that reads _problematicDecoder->Construct();... I end up with the IDE telling me...
"No source available for "Osp::Media::Image::Construct()"
In other words, why can I NOT debug this code when I reference Image *image from a header file?
Any ideas?
Thanks :-)
This usually means you're stepping through some code which you do not posses its source.
I assume here that Osp::Media::Image is a class supplied by Samsung or similar for which you do not have the cpp file. So this means the debugger can't show you the current code line while you're at a function of Osp::Media::Image.
Alternatively, there's a good chance you do have all of the source code for this class, but Eclipse doesn't know where it is. In this case you can add the correct directories under the Debug Configurations window.
Ok, problem solved.
The idea is to first new up an instance of Image like so...
_decoder = new Osp::Media::Image();
And then do _decoder->Construct().
Funny enough, this seems blatantly obvious to me now coming from the C# world, though why the code I posted for workingDecoder works is still somewhat mysterious to me. The fact the sample projects pre-loaded with the bada IDE don't seem to make a call to new() leads me to believe that perhaps those samples are outdated our out of synch.
Either that or I really AM wildly out of the C++ loop.
Anyway thanks so much for the effort guys.
Appreciated :)