Programmatic creation of image button in cppwinrt - c++

Using cppwinrt (standard C++, not C++/CX) how would you set the content of a Button to an image, programmatically? Has to be programmatically because cppwinrt does not yet support xaml, in which doing that is easy. Here's what I am trying, which results in a functional but empty button:
Button button = Button();
BitmapImage bitmapImage = BitmapImage();
Uri imageUri = Uri(L"ms-appx:///Assets/Images/stopbutton.png");
bitmapImage.UriSource(imageUri);
Image buttonImage = Image();
buttonImage.Height(30);
buttonImage.Width(30);
buttonImage.Source(bitmapImage);
button.Content(buttonImage);
Then of course I add the button, which does show up nicely, though blank. I've tried an absolute path for the .png, but that also fails. There must be a way to do this programmatically in C++.

Your original code works fine on my side. Just make sure that your image really is inside the Assets/Images folder, that you added it to your project and that it is copied with the app content during the build, by checking if the Content parameter in the image properties is set to True.
Edit
After reading your further requirements. Just set the button padding and border thickness to zero, this will remove any space around the image.
Here is a simple working application with your button creation code:
#include <winrt\Windows.ApplicationModel.Activation.h>
#include <winrt\Windows.Devices.Enumeration.h>
#include <winrt\Windows.Foundation.h>
#include <winrt\Windows.UI.Xaml.h>
#include <winrt\Windows.UI.Xaml.Controls.h>
#include <winrt\Windows.UI.Xaml.Media.Imaging.h>
using namespace winrt;
using namespace winrt::Windows::ApplicationModel::Activation;
using namespace winrt::Windows::Devices::Enumeration;
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Xaml::Controls;
using namespace winrt::Windows::UI::Xaml::Media::Imaging;
struct App : ApplicationT<App>
{
void OnLaunched(LaunchActivatedEventArgs const &)
{
Image image;
image.Height(30);
image.Width(30);
image.Source(BitmapImage(Uri(L"ms-appx:///Assets/Images/sample.png")));
Button button;
button.Padding(ThicknessHelper::FromUniformLength(0));
button.BorderThickness(ThicknessHelper::FromUniformLength(0));
button.Content(image);
Window window = Window::Current();
window.Content(button);
window.Activate();
}
static void Initialize(ApplicationInitializationCallbackParams const &)
{
make<App>();
}
static void Start()
{
Application::Start(App::Initialize);
}
};
int WINAPI wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
{
App::Start();
}

OK, here is what is needed to make a button display an image that fills the button: rather than setting the button.Content to an image, create an ImageBrush with the image and set the button.Background to that ImageBrush, e.g.
Button button = Button();
button.Height(30);
button.Width(30);
BitmapImage bitmapImage = BitmapImage();
Uri imageUri = Uri(L"ms-appx:///Assets/Images/stopbutton.png");
bitmapImage.UriSource(imageUri);
ImageBrush imageBrush = ImageBrush();
imageBrush.ImageSource(bitmapImage);
button.Background(imageBrush);
//The button will now look exactly like the image.

Related

How to load gif using wxWidgets c++?

I need your help! Im currently really new to wxWidgets as a uni student. I am trying to load a .gif file using wxWidgets. I tried using the code below... but it only loads 1 frame, it doesn't move/ change to the other frames, it's basically a still picture. The file is .gif extension, and it has 3 frames or so. The location of the image is already correct. Help would be much appreciated!
Thank you
#include "ImageWindow.h"
#include <wx/stdpaths.h>
#include <wx/filename.h>
BEGIN_EVENT_TABLE(ImageWindow, wxWindow)
EVT_PAINT(ImageWindow::OnPaint)
END_EVENT_TABLE()
ImageWindow::ImageWindow(wxFrame *parent)
: wxWindow(parent, wxID_ANY)
{
this->SetBackgroundColour(wxColour(*wxWHITE));
wxImageHandler *gifLoader = new wxGIFHandler();
wxImage::AddHandler(gifLoader);
this->LoadPotatoBitmap();
}
ImageWindow::~ImageWindow()
{
delete potatoBitmap;
}
void ImageWindow::LoadPotatoBitmap()
{
wxStandardPaths &stdPaths = wxStandardPaths::Get();
wxString fileLocation = stdPaths.GetExecutablePath();
wxImage image(wxT("A:\\Projects\\TestGif\\Assets\\Kuning.gif"),
wxBITMAP_TYPE_GIF);
potatoBitmap = new wxBitmap(image);
}
void ImageWindow::OnPaint(wxPaintEvent &event)
{
wxPaintDC pdc(this);
if (potatoBitmap != nullptr)
{
pdc.DrawBitmap(*potatoBitmap, wxPoint(150, 100), true);
}
}
You are not specifying the index of the image in the constructor and that's why you see the default one as you can see in the wxWdigets documentation:
wxImage::wxImage ( const wxString & name,
wxBitmapType type = wxBITMAP_TYPE_ANY,
int index = -1
)
index Index of the image to load in the case that the image file contains multiple images. This is only used by GIF, ICO and TIFF handlers. The default value (-1) means "choose the default image" and is interpreted as the first image (index=0) by the GIF and TIFF handler and as the largest and most colourful one by the ICO handler.
But, you should also consider wxAnimationCtrl (see this sample)
Use wxAnimationCtrl for playing gif animations
or
Use extract each frame from the gif image and draw one by one using wxTimer.

captureScreen in cocos-2d C++ - how to use or save the captured image?

I want to have a button in my (iOS) app that takes a screenshot of the current screen and then attaches it to a text message.
Like I have seen in this other app...
I have message sending working, and I think I have screenshot working, but I don't know where the screenshot is saved or how to use it.
My message sending is called from a button in the app...
void GameOverScene::messageCallBack(cocos2d::Ref *sender) {
CocosDenshion::SimpleAudioEngine::getInstance()->playEffect(ALL_BUTTONS_CLICK_SOUND_NAME);
utils::captureScreen( CC_CALLBACK_2(GameOverScene::afterCaptured, this), "screenshot.png" );
__String *messageTextOne = __String::create("sms:&body=Hey,%20I%20just%20hit%20a%20score%20of%20");
__String *messageTextTwo = __String::createWithFormat("%i", score);
__String *messageURL = __String::createWithFormat("%s%s", messageTextOne->getCString(), messageTextTwo->getCString());
Application::getInstance()->openURL(messageURL->getCString());
}
and the screenshot function is...
void GameOverScene::afterCaptured( bool succeed, const std::string &outputFile ) {
if (succeed) {
log("Screen capture succeeded");
Size screenSize = Director::getInstance()->getWinSize();
RenderTexture * tex = RenderTexture::create(screenSize.width, screenSize.height);
tex->setPosition(screenSize.width/2, screenSize.height/2);
tex->begin();
this->getParent()->visit();
tex->end();
tex->saveToFile("Image_Save.png", Image::Format::PNG);
} else {
log("Screen capture failed");
}
}
I get the message in the console "Screen capture succeeded", and my message app opens up with the prefilled text message.
What I need to do is to add the screenshot to this message, but I cant see how to do that, or where the screenshot is saved, or how to use the saved screenshot.
If it succeeded it's saved in private application directory. Use software like iExplorer, find your app and it should be inside Documents directory. If you want to see it in Photos you have manually add it there.
In order to achieve this, you have to call
UIImageWriteToSavedPhotosAlbum
see: How to save picture to iPhone photo library?
You have to create a function in AppController.m and use it from here. You can call objc code from c++. It requires UIImage so first you have to pass filepath and load uiimage from it and then finally add to gallery.
You can use something like this to get the path of image saved:
void CustomLayerColor::saveFile(Node*node, std::string fileName, const renderTextureCallback& callBack) {
float renderTextureWidth = node->getBoundingBox().size.width;
float renderTextureHeight = node->getBoundingBox().size.height;
RenderTexture * renderTexture = RenderTexture::create(renderTextureWidth,renderTextureHeight);
renderTexture->begin();
node->visit();
renderTexture->end();
renderTexture->saveToFile(fileName, Image::Format::PNG, true,callBack);
}
void CustomLayerColor::onSaveFileCallBack(RenderTexture * mRenderTexture, const std::string& savedFileNameWithFullPath) {
}

Event handler of another frame not getting called - wxWidgets

Good day to all,
I'm working on a C++ program using wxWidgets wherein a frame has a button named "Calibrate Button" which is used to calibrate HSV values using a trackbar. When the user selects this button, a live feed video, a control panel which contains the trackbar for adjusting HSV values, a threshold image which represents the changes in the calibration of the HSV values, and another frame which contains a button named "SAVE VALUES" appears. When the user clicks the Save Values button, it saves whatever the values that have been set in the trackbar into a textfile.
My problem is, whenever i click that button, it does not perform what it is intended to do, which is to save the HSV values in a txtfile.
Here is the main code which is responsible for creating the additional frame when the user selects the Calibrate Button.
void TemplateFrame::OncalibTrackerButtonClick(wxCommandEvent& event)
{
**some code for initializing the live video feed, the trackbars, etc.**
CalibrationWindow* calibWindow = new CalibrationWindow(this);
calibWindow->setHSVvalues(H_MIN,S_MIN,V_MIN,H_MAX,S_MAX,V_MAX);
calibrationModeTracker = true;
**the following code after this line would be a pseudocode of what I am doing once the button has been click already
while(calibrationModeTracker){
calibWindow->Show(); // shows the "SAVE VALUES" frame
wxYield();
read live feed video
createTrackbars();
show live feed video
show threshold image
}
}
Inside the while loop, users would be able to click the "SAVE VALUES" button which would save the HSV values in a txtfile.
On the other hand, here is the event handler function of the newly created frame (CalibrationWindow.cpp) after clicking Calibrate Button which contains the Save Values button
void CalibrationWindow::OnSaveClick(wxCommandEvent& event)
{
ofstream myfile;
stringstream oss(stringstream::in | stringstream::out);
string f;
f = "//home//ianlangley//Desktop//Savefiles//HSVvalues_left.txt";
f = f.append(oss.str());
myfile.open(f.c_str());
if (myfile.is_open()){
myfile<<CalibrationWindow::getlow_H()<<"\n";
myfile<<CalibrationWindow::getlow_S()<<"\n";
myfile<<CalibrationWindow::getlow_V()<<"\n";
myfile<<CalibrationWindow::gethigh_H()<<"\n";
myfile<<CalibrationWindow::gethigh_S()<<"\n";
myfile<<CalibrationWindow::gethigh_V();
myfile.close();
}
}
Lastly, here is the code inside the header file: CalibrationWindow.h
class CalibrationWindow: public wxFrame
{
public:
CalibrationWindow(wxWindow* parent,wxWindowID id=wxID_ANY);
virtual ~CalibrationWindow();
void setHSVvalues(int lowH,int lowS, int lowV,int highH,int highS, int highV);
int getlow_H();
int getlow_S();
int getlow_V();
int gethigh_H();
int gethigh_S();
int gethigh_V();
//(*Declarations(CalibrationWindow)
wxButton* LeftHandButton;
wxButton* RightHandButton;
//*)
protected:
//(*Identifiers(CalibrationWindow)
static const long ID_BUTTON2;
static const long ID_BUTTON1;
//*)
private:
int lowH,lowS,lowV,highH,highS,highV;
//(*Handlers(CalibrationWindow)
void OnRightHandButtonClick(wxCommandEvent& event);
void OnLeftHandButtonClick(wxCommandEvent& event);
//*)
DECLARE_EVENT_TABLE()
};
Thank you to those who will be able to help me with this problem.

CTreeCntrl: SetItemImage cause the redraw of whole item

I need to implement something like animated tree images. So I have 4 states of the same icon, for just testing it I have created VS 2010 new project and add just handler for ON_WM_TIMER and in function add (700 msec timer)
void CClassView::OnTimer(UINT_PTR nIDEvent)
{
HTREEITEM hItem = m_wndClassView.GetRootItem();
HTREEITEM hCurSel = m_wndClassView.GetNextItem(hItem, TVGN_CHILD );
int nImage, nSelImage;
m_wndClassView.GetItemImage(hCurSel, nImage,nSelImage);
int nNewImgae = nImage == 4 ? 1 : nImage+1;
m_wndClassView.SetItemImage(hCurSel, nNewImgae, nNewImgae);
}
So everything is fine my icon became animated and moving ,but sometimes I see that whole tree item redrawing (not only icon image but item image with text). So is there any possibility to fix it?

MFC - Printing - Changing page orientation from a custom pagesetup dialog

I am developing a custom print dialog and page setup using MFC and VS2008 for my Win32 program. Since the code is legacy, I can't take much advantage from MFC view/doc architecture. As a result, I wrote a printing code completely from scratch.
I setup CPrintInfo, instantiate my custom print dialog box and hook this dialog box to the CPrintInfo I just created. When my custom print dialog is up, I have a radio button to let a user toggles the page orientation. For some reasons, I couldn't modify the current DEVMODE at the run-time. As a result, every page I print will end up as a portrait.
Even if I manually set pDevMode->dmOrientation to DMORIENT_LANDSCAPE from the event handler of the custom print dialog, the printing result is still ended up as portrait. I am really not sure why this is happening and how to modify the DevMode after the print dialog is up.
Thank you in advance for any help.
Here is the code I have:
void PrintSomething(CWnd* currentWnd) {
// Create CPrintInfo
CPrintInfo* pPrintInfo = new CPrintInfo;
SetupPrintInfo(pPrintInfo); // simply setup some member variables of CPrintInfo
// Create a custom print dialog
CustomPrintDlg* pCustomPrtDlg = new CustomPrintDlg(FALSE, PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUMS
| PD_HIDEPRINTTOFILE | PD_NOSELECTION, pPrintInfo, currentWnd);
SetupPrintDialog(pPrintInfo,pCustomPrtDlg);
if ( AfxGetApp()->DoPrintDialog(pCustomPrtDlg) == IDOK ) {
... // proceed a print loop
}
}
Code for setting up the custom print dialog:
void SetupPrintDialog(CPrintInfo* pPrintInfo,CustomPrintDlg* pCustomPrtDlg) {
delete pInfo->m_pPD;
pInfo->m_pPD = pCustomPrtDlg;
pInfo->m_pPD->m_pd.hInstance = AfxGetInstanceHandle();
pInfo->m_pPD->m_pd.lpPrintTemplateName = MAKEINTRESOURCE(IDD_CUSTOM_PRTDLG);
// Set the Flags of the PRINTDLG structure as shown, else the
// changes will have no effect.
pInfo>m_pPD->m_pd.Flags |= PD_ENABLEPRINTTEMPLATE;
// Set the page range.
pInfo>m_pPD->m_pd.nMinPage = 1; // one based page numbers.
pInfo>m_pPD->m_pd.nMaxPage = 0xffff; // how many pages is unknown.
}
When a user toggles the radio button to Landscape, this function will be invoked:
void CustomPrintDlg::OnLandscapeChecked() {
// set the current Devmode to landscape
LPDEVMODE pDevMode = GetDevMode();
GlobalUnlock(pDevMode);
pDevMode->dmOrientation = DMORIENT_LANDSCAPE;
}
A pseucode for the custom print dialog class:
class CustomPrintDlg: public CPrintDialog {
... // just override some methods from CPrintDialog
};
Thanks again,
Unagi
I figured out the solution:
All I need is to call GlobalLock to obtain a pointer to the Devmode before changing the current DevMode.
void CustomPrintDlg::OnLandscapeChecked()
{
// set the current Devmode to landscape
LPDEVMODE pDevMode = GetDevMode();
GlobalLock(pDevMode);
pDevMode->dmOrientation = DMORIENT_LANDSCAPE;
GlobalUnlock(pDevMode)
}
Thanks again for helping me.
Nowhere in your example code do you show how you're creating the DC for printing. When you call CreateDC, you must pass a pointer to a DEVMODE structure; this defines whether the printing will be portrait or landscape.