How to detect network change events asynchronously using c++ WinRT - c++

networkStatusCallback = new NetworkStatusChangedEventHandler(OnNetworkStatusChange);
if (!registeredNetworkStatusNotif)
{
NetworkInformation.NetworkStatusChanged += networkStatusCallback;
registeredNetworkStatusNotif = true;
}
I'm getting the error NetworkInformation.NetworkStatusChanged += networkStatusCallback

This will get you started. It's some code I cobbled together.
It doesn't do error checking. You should check the HRESULT or error code from each major function invoked below.
It doesn't show you how to implement INetworkStatusChangedEventHandler. You have to implement an implementation of that class yourself using the standard COM principals.
You'll need to link with runtimeobjects.lib for RoGetActivationFactory.
#include <windows.h>
#include <roapi.h>
#include <Windows.Networking.h>
#include <Windows.Networking.Connectivity.h>
using ABI::Windows::Networking::Connectivity::INetworkInformationStatics;
using ABI::Windows::Networking::Connectivity::INetworkStatusChangedEventHandler;
int main()
{
CoInitialize(nullptr);
HSTRING hstr = nullptr;
IActivationFactory* pFactory = nullptr;
INetworkInformationStatics* pStatics = nullptr;
EventRegistrationToken token = {};
const wchar_t* interfaceName = RuntimeClass_Windows_Networking_Connectivity_NetworkInformation;
::WindowsCreateString(interfaceName, (DWORD)(wcslen(interfaceName)), &hstr);
::RoGetActivationFactory(hstr, IID_IActivationFactory, (void**)&pFactory);
WindowsDeleteString(hstr);
INetworkStatusChangedEventHandler* pHandler = <ptr to com object you create that implements INetworkStatusChangedEventHandler>
pFactory->QueryInterface(&pStatics);
pStatics->add_NetworkStatusChanged(pHandler, &token);
return 0;
}

Related

How to use Win32 ThreadPool API?

This version (based on this article) works:
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
VOID
CALLBACK
MyWorkCallback(
PTP_CALLBACK_INSTANCE Instance,
PVOID Parameter,
PTP_WORK Work
)
{
// Instance, Parameter, and Work not used in this example.
UNREFERENCED_PARAMETER(Instance);
UNREFERENCED_PARAMETER(Parameter);
UNREFERENCED_PARAMETER(Work);
DWORD threadId = GetCurrentThreadId();
BOOL bRet = FALSE;
//
// Do something when the work callback is invoked.
//
{
_tprintf(_T("MyWorkCallback: ThreadId = %d Task performed.\n"), threadId);
}
return;
}
int main()
{
TP_CALLBACK_ENVIRON CallBackEnviron;
PTP_POOL pool = NULL;
PTP_CLEANUP_GROUP cleanupgroup = NULL;
PTP_WORK_CALLBACK workcallback = MyWorkCallback;
PTP_TIMER timer = NULL;
PTP_WORK work = NULL;
InitializeThreadpoolEnvironment(&CallBackEnviron);
pool = CreateThreadpool(NULL);
SetThreadpoolThreadMaximum(pool, 1);
SetThreadpoolThreadMinimum(pool, 3);
cleanupgroup = CreateThreadpoolCleanupGroup();
SetThreadpoolCallbackPool(&CallBackEnviron, pool);
SetThreadpoolCallbackCleanupGroup(&CallBackEnviron, cleanupgroup, NULL);
work = CreateThreadpoolWork(workcallback, NULL, &CallBackEnviron);
for (int i = 0; i < 10; ++i)
{
SubmitThreadpoolWork(work);
}
}
However, this version also works (with the same work function from above):
int main()
{
PTP_WORK = CreateThreadpoolWork(workcallback, NULLPTR, NULLPTR);
for (int i = 0; i < 10; ++i)
{
SubmitThreadpoolWork(work);
}
}
What are the differences between the two versions (except for the minimum and maximum thread count)?
Why would I use one version over another?
This is covered in the documentation for InitializeThreadpoolEnvironment:
Create a callback environment if you plan to call one of the following functions to modify the environment:
SetThreadpoolCallbackCleanupGroup
SetThreadpoolCallbackLibrary
SetThreadpoolCallbackPool
SetThreadpoolCallbackPriority
SetThreadpoolCallbackRunsLong
If you need the functionality provided by one or more of the listed functions, then you need to create a callback environment. If you don't, you don't.
If in doubt when starting a new project, use the simple approach to begin with, and see whether it meets your needs. You can always go back and switch to the more complex variant if and when it becomes necessary.

How to wait for data on a COM port

I am using .Net framework's SerialPort class (System.IO.Ports) and am trying to wait to receive data. I've looked around and the WaitCommEvent function seems to be what people suggest using, however it expects a HANDLE as the first parameter. I would like to know either how to get a handle from the SerialPort or a different way to wait for data compatible with the SerialPort class.
The SerialPort class has a DataReceived event:
Indicates that data has been received through a port represented by the SerialPort object.
The documentation provides the following C++/CLI example:
#using <System.dll>
using namespace System;
using namespace System::IO::Ports;
ref class PortDataReceived
{
public:
static void Main()
{
SerialPort^ mySerialPort = gcnew SerialPort("COM1");
mySerialPort->BaudRate = 9600;
mySerialPort->Parity = Parity::None;
mySerialPort->StopBits = StopBits::One;
mySerialPort->DataBits = 8;
mySerialPort->Handshake = Handshake::None;
mySerialPort->RtsEnable = true;
mySerialPort->DataReceived += gcnew SerialDataReceivedEventHandler(DataReceivedHandler);
mySerialPort->Open();
Console::WriteLine("Press any key to continue...");
Console::WriteLine();
Console::ReadKey();
mySerialPort->Close();
}
private:
static void DataReceivedHandler(
Object^ sender,
SerialDataReceivedEventArgs^ e)
{
SerialPort^ sp = (SerialPort^)sender;
String^ indata = sp->ReadExisting();
Console::WriteLine("Data Received:");
Console::Write(indata);
}
};
int main()
{
PortDataReceived::Main();
}

Native IIS7.5 Module not running

I've created a simple CHttpModule that adds a custom header to all requests:
#define _WINSOCKAPI_
#include <windows.h>
#include <sal.h>
#include <httpserv.h>
class AppendHeaderModule : public CHttpModule {
public:
REQUEST_NOTIFICATION_STATUS
OnBeginRequest(
IN IHttpContext * pHttpContext,
IN IHttpEventProvider * pProvider
)
{
UNREFERENCED_PARAMETER(pProvider);
PCSTR testHeaderName = "Foo";
PCSTR testHeader = "bar";
pHttpContext->GetResponse()->SetHeader(testHeaderName, testHeader, (USHORT)strlen(testHeader), true);
return RQ_NOTIFICATION_CONTINUE;
}
VOID Terminate() {
delete this;
}
AppendHeaderModule() { }
~AppendHeaderModule() { }
};
class AppendHeaderModuleFactory : public IHttpModuleFactory {
public:
HRESULT
GetHttpModule(
OUT CHttpModule ** ppModule,
IN IModuleAllocator * pAllocator
)
{
UNREFERENCED_PARAMETER(pAllocator);
AppendHeaderModule* pModule = new AppendHeaderModule;
if (!pModule) {
return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
}
else {
*ppModule = pModule;
pModule = NULL;
return S_OK;
}
}
void Terminate() {
delete this;
}
};
HRESULT __stdcall
RegisterModule(
DWORD dwServerVersion,
IHttpModuleRegistrationInfo * pModuleInfo,
IHttpServer * pGlobalInfo
)
{
UNREFERENCED_PARAMETER(dwServerVersion);
UNREFERENCED_PARAMETER(pGlobalInfo);
AppendHeaderModuleFactory* pModule = new AppendHeaderModuleFactory;
if (pModule == NULL)
return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
return pModuleInfo->SetRequestNotifications(pModule, RQ_BEGIN_REQUEST, 0);
}
I've copied it to C:\Windows\System32\inetsrv, registered the module, and added it to the list. However, I'm not seeing the additional header in any of my requests. I created a similar managed module, installed it to the GAC, registered it, and it works fine. But this native module seems to do nothing. Is there another step required to get native modules to handle requests?
Also, I'm not sure if it matters, but the requests are being made to an ASP.NET site. Do native handlers not run for ASP.NET?
If the module is a 32-bit module you need to enable 32-bit applications in the application pool for your website. Go to the Application Pools, select the pool for your website, Advanced Settings and set "Enable 32-Bit Applications to TRUE.

Get system brightness event in windows

Can somebody will guide me how to get brightness changes event using vc++ in windows system?
or I need to get brightness slider value whenever it will change.
Any help will be very appreciated.
Thanks in advance.
A late answer but since I have been looking for the same thing. Although it is true that controlling brightness is not a Windows task but sometimes a driver's task and could also be related directly to ACPI calls, we can still get some information from Windows about its changes by implementing WMI Events. In particular, you will need to implement WmiMonitorBrightnessEvent which will give you the information you need whenever Windows receives an event of brightness change. The sample code below is a direct conversion to C++/CLI of the C# code in #RRUZ answer here where he made use of WmiMonitorBrightnessEvent.
EventWatcherAsync.h
#pragma once
using namespace System;
using namespace System::Management;
ref class EventWatcherAsync
{
public:
void WmiEventHandler(Object^ sender, EventArrivedEventArgs^ e);
EventWatcherAsync();
};
EventWatcherAsync.cpp
#include "stdafx.h"
#include "EventWatcherAsync.h"
void EventWatcherAsync::WmiEventHandler(Object^ sender, EventArrivedEventArgs^ e)
{
Console::WriteLine("Active : " + e->NewEvent->Properties["Active"]->Value->ToString());
Console::WriteLine("Brightness : " + e->NewEvent->Properties["Brightness"]->Value->ToString());
Console::WriteLine("InstanceName : " + e->NewEvent->Properties["InstanceName"]->Value->ToString());
}
EventWatcherAsync::EventWatcherAsync()
{
try
{
System::String^ ComputerName = "localhost";
System::String^ WmiQuery;
ManagementEventWatcher^ Watcher;
ManagementScope^ Scope;
if (ComputerName != "localhost")
{
ConnectionOptions^ Conn = gcnew ConnectionOptions();
Conn->Username = "";
Conn->Password = "";
Conn->Authority = "ntlmdomain:DOMAIN";
Scope = gcnew ManagementScope(String::Format("\\\\{0}\\root\\WMI", ComputerName), Conn);
}
else
Scope = gcnew ManagementScope(String::Format("\\\\{0}\\root\\WMI", ComputerName));
Scope->Connect();
WmiQuery = "Select * From WmiMonitorBrightnessEvent";
Watcher = gcnew ManagementEventWatcher(Scope, gcnew EventQuery(WmiQuery));
Watcher->EventArrived += gcnew EventArrivedEventHandler(this, &EventWatcherAsync::WmiEventHandler);
Watcher->Start();
Console::Read();
Watcher->Stop();
}
catch (Exception^ e)
{
Console::WriteLine("Exception {0} Trace {1}", e->Message, e->StackTrace);
}
}
Main.cpp
#include "stdafx.h"
#include "EventWatcherAsync.h"
using namespace System;
int main(array<System::String ^> ^args)
{
Console::WriteLine("Listening {0}", "WmiMonitorBrightnessEvent");
Console::WriteLine("Press Enter to exit");
EventWatcherAsync^ eventWatcher = gcnew EventWatcherAsync();
Console::Read();
return 0;
}

C++ error: Invalid use of incomplete type ...

I have a small- to medium-size project that I am doing for my software engineering course this semester. I have chosen to do it in C++ (gtkmm). I am doing okay so far but I have run into a problem with circular references or the following errors:
Login_Dialog.cpp:25: error: invalid use of incomplete type ‘struct MainWindow’
Login_Dialog.h:12: error: forward declaration of ‘struct MainWindow’
make: *** [Login_Dialog.o] Error 1
In short I have about 10 classes and I know in the future they are all going to need to talk to each other. I have run into one specific case so far, and I have been trying to resolve it on my own, but I am totally stuck.
My program has a main window class that is defined as follows:
/*
* MainWindow.h
*/
#ifndef MAINWINDOW_H_
#define MAINWINDOW_H_
#include "includes.h"
#include "ModelDrawing.h"
#include "ViewDrawing.h"
#include "ControlerDrawing.h"
#include "ModelChat.h"
#include "ViewChat.h"
#include "ControlerChat.h"
#include "ModelQueue.h"
#include "ViewQueue.h"
#include "ControlerQueue.h"
#include "Login_Dialog.h"
#include "TCP_IP_Socket.h"
class MainWindow : public Window
{
public:
MainWindow(int type);
~MainWindow();
void on_menu_file_new_generic();
void on_menu_file_quit();
ModelDrawing* get_mdl_Draw();
ViewDrawing* get_view_Draw();
ControlerDrawing* get_cntrl_Draw();
ModelChat* get_mdl_Chat();
ViewChat* get_view_Chat();
ControlerChat* get_cntrl_Chat();
ModelQueue* get_mdl_Que();
ViewQueue* get_view_Que();
ControlerQueue* get_cntrl_Que();
Label* get_status_label();
void set_status_label(Glib::ustring label);
TCP_IP_Socket* get_socket();
private:
TCP_IP_Socket* socket;
Widget* menu;
RefPtr<Gtk::ActionGroup> m_refActionGroup;
RefPtr<Gtk::UIManager> m_refUIManager;
ModelDrawing* mdl_Draw;
ViewDrawing* view_Draw;
ControlerDrawing* cntrl_Draw;
ModelChat* mdl_Chat;
ViewChat* view_Chat;
ControlerChat* cntrl_Chat;
ModelQueue* mdl_Que;
ViewQueue* view_Que;
ControlerQueue* cntrl_Que;
Frame* label_frame;
Label* status_label;
Login_Dialog* login;
protected:
//Containers
HBox* main_HBox;
VBox* base_VBox;
};
#endif /* MAINWINDOW_H_ */
The functions are defined as follows:
/*
* MainWindow.cpp
*/
#include "MainWindow.h"
MainWindow::MainWindow(int type)
{
this->socket = new TCP_IP_Socket(this);
//Login Section
this->login = new Login_Dialog(WINDOW_TOPLEVEL, this);
int status;
status = this->login->run();
if(status == 0)
{
exit(1);
}
this->login->hide();
//By Default Create and Open Up Student Queue
this->mdl_Que = new ModelQueue(this);
this->view_Que = new ViewQueue(this);
this->cntrl_Que = new ControlerQueue(this, (this->mdl_Que), (this->view_Que));
this->set_default_size(1200, 750);
this->set_border_width(1);
this->set_title("Tutor App");
this->base_VBox = manage(new VBox());
this->main_HBox = manage(new HBox());
this->label_frame = manage(new Frame());
m_refActionGroup = Gtk::ActionGroup::create();
m_refUIManager = Gtk::UIManager::create();
m_refActionGroup->add(Gtk::Action::create("FileMenu", "File"));
this->add_accel_group(m_refUIManager->get_accel_group());
Glib::ustring ui_info =
"<ui>"
"<menubar name='MenuBar'>"
" <menu action='FileMenu'>"
" </menu>"
"</menubar>"
"</ui>";
m_refUIManager->insert_action_group(m_refActionGroup);
m_refUIManager->add_ui_from_string(ui_info);
this->menu = m_refUIManager->get_widget("/MenuBar");
this->mdl_Draw = new ModelDrawing(this);
this->view_Draw = new ViewDrawing(this);
this->cntrl_Draw = new ControlerDrawing(this, (this->mdl_Draw), (this->view_Draw));
this->mdl_Chat = new ModelChat(this);
this->view_Chat = new ViewChat(this);
this->cntrl_Chat = new ControlerChat(this, (this->mdl_Chat), (this->view_Chat));
this->status_label = manage(new Label("Welcome to The Tutor App", ALIGN_LEFT, ALIGN_LEFT, false));
//Put it all together
this->main_HBox->pack_start(*(this->view_Draw->get_left_VBox()));
this->label_frame->add(*(this->status_label));
this->base_VBox->pack_end(*(this->label_frame));
this->main_HBox->pack_end(*(this->view_Chat->get_right_VBox()));
this->base_VBox->pack_start(*(this->menu), Gtk::PACK_SHRINK);
this->base_VBox->pack_end(*(this->main_HBox), true, true);
this->label_frame->set_size_request(-1, 5);
this->add(*(this->base_VBox));
this->show_all();
this->view_Que->get_window()->show_all();
}
MainWindow::~MainWindow()
{
}
ModelDrawing* MainWindow::get_mdl_Draw()
{
return NULL;
}
ViewDrawing* MainWindow::get_view_Draw()
{
return NULL;
}
ControlerDrawing* MainWindow::get_cntrl_Draw()
{
return NULL;
}
ModelChat* MainWindow::get_mdl_Chat()
{
return NULL;
}
ViewChat* MainWindow::get_view_Chat()
{
return NULL;
}
ControlerChat* MainWindow::get_cntrl_Chat()
{
return NULL;
}
ModelQueue* MainWindow::get_mdl_Que()
{
return NULL;
}
ViewQueue* MainWindow::get_view_Que()
{
return this->view_Que;
}
ControlerQueue* MainWindow::get_cntrl_Que()
{
return NULL;
}
Label* MainWindow::get_status_label()
{
return this->status_label;
}
void MainWindow::set_status_label(Glib::ustring label)
{
this->status_label->set_label(label);
}
TCP_IP_Socket* MainWindow::get_socket()
{
return this->socket;
}
void MainWindow::on_menu_file_quit()
{
hide(); //Closes the main window to stop the Gtk::Main::run().
}
void MainWindow::on_menu_file_new_generic()
{
std::cout << "A File|New menu item was selected." << std::endl;
}
Now the main window creates a TCP_IP_Socket class and a login dialog. I first create the connection and set a few strings (seen in the code below):
/*
* TCP_IP_Socket.cpp
*/
#include "TCP_IP_Socket.h"
TCP_IP_Socket::TCP_IP_Socket(MainWindow* hwnd)
{
this->hwnd = hwnd;
server_name = "www.geoginfo.com";
this->set_server_ustring(this->server_name);
printf("%s", this->server_name);
struct addrinfo specs;
struct addrinfo* results;
int status;
memset(&specs, 0, sizeof specs);
specs.ai_flags = 0;
specs.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version
specs.ai_socktype = SOCK_STREAM;
if ((status = getaddrinfo(this->server_name, NULL, &specs, &results)) != 0)
{
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
exit(0);
}
char ipstr[INET6_ADDRSTRLEN];
void* addr;
if (results->ai_family == AF_INET)
{ // IPv4
struct sockaddr_in* ipv4 = (struct sockaddr_in*)results->ai_addr;
addr = &(ipv4->sin_addr);
}
else
{ // IPv6
struct sockaddr_in6* ipv6 = (struct sockaddr_in6 *)results->ai_addr;
addr = &(ipv6->sin6_addr);
}
inet_ntop(results->ai_family, addr, ipstr, sizeof ipstr);
this->set_serverip_ustring(ipstr);
printf(" = %s\n", ipstr);
freeaddrinfo(results); // free the linked list
printf("\n");
}
TCP_IP_Socket::~TCP_IP_Socket()
{
}
void TCP_IP_Socket::set_server_ustring(const char* server_name)
{
this->server_domainname = new ustring(server_name);
}
void TCP_IP_Socket::set_serverip_ustring(const char* ip)
{
this->server_ip = new ustring(ip);
}
Glib::ustring* TCP_IP_Socket::get_server_domainname()
{
return this->server_domainname;
}
Glib::ustring* TCP_IP_Socket::get_server_ip()
{
return this->server_ip;
}
and then I create the login and try to access the server_ip ustring and server_domainname ustring from my login dialog:
/*
* Login_Dialog.cpp
*/
#include "Login_Dialog.h"
Login_Dialog::Login_Dialog(int type, MainWindow* hwnd)
{
this->hwnd = hwnd;
this->set_default_size(100, 150);
this->user_layout = manage(new HBox());
this->pswd_layout = manage(new HBox());
this->user_name = manage(new Label("Username"));
this->user_entry = manage(new Entry());
this->pswd_user = manage(new Label("Password"));
this->pswd_entry = manage(new Entry());
this->Ok = add_button("Ok", 1);
this->Cancel = add_button("Cancel", 0);
Glib::ustring* one = hwnd->get_socket()->get_server_domainname();
this->status_label = manage (new Label("This is a test", ALIGN_LEFT, ALIGN_LEFT, false));
this->Ok->set_size_request(74, -1);
this->Cancel->set_size_request(74, -1);
this->user_layout->pack_start(*(this->user_name), true, true);
this->user_layout->pack_end(*(this->user_entry), true, true);
this->pswd_layout->pack_start(*(this->pswd_user), true, true);
this->pswd_layout->pack_end(*(this->pswd_entry), true, true);
this->get_vbox()->pack_start(*(this->user_layout));
this->get_vbox()->pack_end(*(this->status_label), true, true);
this->get_vbox()->pack_end(*(this->pswd_layout));
show_all(); //<-- This is key
}
void Login_Dialog::set_status_label(Glib::ustring label)
{
this->status_label->set_label(label);
}
When I try to compile this I get the error listed at the very top of this post. If I remove class MainWindow; and replace it with #include "MainWindow.h", I run into circular reference issues with headers.
I know I posted a lot of code, but I didn't want to get flamed for not posting enough.
You can get away with forward declaring MainWindow in Login_Dialog.h as long as you only forward declar a pointer to the type (which you do), and you add this to the top of Login_Dialog.h so the compiler knows to expect to see a class declaration at some later time.
class MainWindow;
Then in Login_Dialog.cpp, include "mainwindow.h" like this.
/*
* Login_Dialog.cpp
*
* Created on: Mar 2, 2010
* Author: Matthew
*/
#include "Login_Dialog.h"
#include "MainWindow.h"
That should do it.
When I try and do this I get the error presented at the very top of this post. If I try and remove the class MainWindow; and replace it with #include "MainWindow.h" I run into circular reference issues with headers.
But this is the issue. You need to move the implementation into a separate implementation (.cpp) file. You can use forward declarations to break circular references in header files, but you have to have both headers available before you attempt to use your type.
You have to include the full definition of you class before you can use it -- not just a forward declaration. Forward declarations are only useful to other forward declarations -- the compiler needs to know what type it's working with before it can generate code.
To fix the error you should replace #include "Login_Dialog.h" with forward declaration of Login_Dialog class in Main_Window.h. Then include Login_Dialog.h in Main_Window.cpp and Main_Window.h in Login_Dialog.cpp. BTW, the same can be done for many other files/classes.