I am trying to write a simple CLR-Windows Form Application. It will show a window having a button. As soon as you click the button, it will hide one of the open Windows. To achieve this I am calling ShowWindow(00050214, false );, where 00050214 is the handle of the Window I am hiding.
But it is giving error:
Error 1 error C3861: 'ShowWindow': identifier not found c:\users\afnan
\documents \visual studio 2010\projects\winformtest\winformtest\Form1.h 80
Please see the last lines of .h file given below, to see how I am using the above function.
WinformTest.cpp : main project file.
#include "stdafx.h"
#include "Form1.h"
#include"windows.h"
using namespace WinformTest;
[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
// Enabling Windows XP visual effects before any controls are created
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
// Create the main window and run it
Application::Run(gcnew Form1());
return 0;
}
Here is .h file
#pragma once
namespace WinformTest {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
/// <summary>
/// Summary for Form1
/// </summary>
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
//
//TODO: Add the constructor code here
//
}
protected:
/// <summary>
/// Clean up any resources being used.
/// </summary>
~Form1()
{
if (components)
{
delete components;
}
}
private: System::Windows::Forms::Button^ button1;
protected:
private:
/// <summary>
/// Required designer variable.
/// </summary>
System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
this->button1 = (gcnew System::Windows::Forms::Button());
this->SuspendLayout();
//
// button1
//
this->button1->Location = System::Drawing::Point(91, 51);
this->button1->Name = L"button1";
this->button1->Size = System::Drawing::Size(75, 23);
this->button1->TabIndex = 0;
this->button1->Text = L"button1";
this->button1->UseVisualStyleBackColor = true;
this->button1->Click += gcnew System::EventHandler(this,
&Form1::button1_Click);
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(284, 262);
this->Controls->Add(this->button1);
this->Name = L"Form1";
this->Text = L"Form1";
this->ResumeLayout(false);
}
#pragma endregion
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
ShowWindow(00050214, false );
}
};
}
UPDATE
I have now put windows.h in form.h file, and used ShowWindow((HWND)0x00050214, SW_HIDE);
but now I am getting:
Error 1 error LNK2028: unresolved token (0A000011) "extern "C" int __stdcall
ShowWindow(struct HWND__ *,int)" (?ShowWindow##$$J18YGHPAUHWND__##H#Z) referenced in function
"private: void __clrcall WinformTest::Form1::button1_Click(class System::Object ^,class
System::EventArgs ^)"
(?button1_Click#Form1#WinformTest##$$FA$AAMXP$AAVObject#System##P$AAVEventArgs#4##Z)
C:\Users\Afnan\Documents\Visual Studio 2010\Projects\WinformTest\WinformTest\WinformTest.obj
Error 2 error LNK2019: unresolved external symbol "extern "C" int __stdcall
ShowWindow(struct HWND__ *,int)" (?ShowWindow##$$J18YGHPAUHWND__##H#Z) referenced in function
"private: void __clrcall WinformTest::Form1::button1_Click(class System::Object ^,class
System::EventArgs ^)"
(?button1_Click#Form1#WinformTest##$$FA$AAMXP$AAVObject#System##P$AAVEventArgs#4##Z)
C:\Users\Afnan\Documents\Visual Studio 2010\Projects\WinformTest\WinformTest\WinformTest.obj
Error 3 error LNK1120: 2 unresolved externals C:\Users\Afnan\Documents\Visual
Studio 2010\Projects\WinformTest\Debug\WinformTest.exe 1
How do put handle? I got this handle using spy++ tool. It also shows caption corresponding to the handle expressed in numbers. The corresponding handle in my case is: WinformTest - Microsoft Visual Studio
Your header file does not include windows.h and so the symbol ShowWindow is not known to it.
The way you call ShowWindow is also wrong. The second parameter is an int and you want to pass SW_HIDE. And I bet that your window handle is actually a hex number.
ShowWindow((HWND)0x00050214, SW_HIDE);
As an aside, I'm not sure why you put so much code in the header file. Normally you would declare the class in the header file and then define the implementation in the cpp file.
Related
I tried to make a C++ GUI program, i started with an empty project, and then add source file which is UI->windows form, and made a main function to call it. But when i tried to run it, it always shows this error
C1001 An internal error has occurred in the compiler
I also set the linker->system->subsystem into windows(/subsystem:windows)
and set entry point to my main function.
this is my main cpp file.
#include "MyForm.h"
using namespace Project1;
using namespace System::Windows::Forms;
using namespace System::Windows;
int main()
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
Project1::MyForm form;
Application::Run(% form);
}
this is my header file(automaticaly created by VS)
#pragma once
namespace Project1 {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
/// <summary>
/// Summary for MyForm
/// </summary>
public ref class MyForm : public System::Windows::Forms::Form
{
public:
MyForm(void)
{
InitializeComponent();
//
//TODO: Add the constructor code here
//
}
protected:
/// <summary>
/// Clean up any resources being used.
/// </summary>
~MyForm()
{
if (components)
{
delete components;
}
}
private:
/// <summary>
/// Required designer variable.
/// </summary>
System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
this->SuspendLayout();
//
// MyForm
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(1089, 508);
this->Name = L"MyForm";
this->Text = L"MyForm";
this->ResumeLayout(false);
}
#pragma endregion
};
}
it has over 2k warning, i can't possibly put it all here
i'm working on my first C++ project that requires a form and I've seemed to have gone in way over my head. largely I believe my issue has to do with that I'm not multi threading my form, but I'm unsure of the proper implementation. I was hoping someone could point out to me exactly where I've gone and made myself look like a muppet. (warning for the feint of heart, I used global variables to quickly create a proof of concept, once I have everything working more or less correctly I'll go back and properly protect everything)
*edit: I guess to clarify, it looks like the issue is that i execute everything in the main thread, its is possible to create a single new thread for the entire form or do i need to create a new thread for each individual control on the form?
Winmain.cpp
main function where I initialize the form and update the information on the form / refresh the form.
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
using namespace Interface;
cooldowns ^ CDwin = gcnew cooldowns;
CDwin->Show();
CDwin->Location = Point(0,0);
while (true)
{
CDwin->timer1->Text = timer1Duration.ToString();
CDwin->timer1Progress->Value = timer1Value;
CDwin->timer1->Refresh();
CDwin->timer1Progress->Refresh();
//collect info to populate CDwin values for next cycle
//something tells me this sleep could be part of the problem?
Sleep(50);
}
}
form.h
#pragma once
namespace Interface {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::Threading;
/// <summary>
/// Summary for cooldowns
/// </summary>
public ref class cooldowns : public System::Windows::Forms::Form
{
public:
cooldowns(void)
{
InitializeComponent();
//
//TODO: Add the constructor code here
//
}
protected:
/// <summary>
/// Clean up any resources being used.
/// </summary>
~cooldowns()
{
if (components)
{
delete components;
}
}
public: System::Windows::Forms::ProgressBar^ timer1Progress;
protected:
public: System::Windows::Forms::Label^ timer1;
private:
/// <summary>
/// Required designer variable.
/// </summary>
System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
this->timer1Progress = (gcnew System::Windows::Forms::ProgressBar());
this->timer1 = (gcnew System::Windows::Forms::Label());
this->SuspendLayout();
//
// timer1Progress
//
this->timer1Progress->ForeColor = System::Drawing::Color::Fuchsia;
this->timer1Progress->Location = System::Drawing::Point(3, 12);
this->timer1Progress->Maximum = 30000;
this->timer1Progress->Name = L"timer1Progress";
this->timer1Progress->Size = System::Drawing::Size(244, 18);
this->timer1Progress->Style = System::Windows::Forms::ProgressBarStyle::Continuous;
this->timer1Progress->TabIndex = 0;
this->timer1Progress->Value = 10000;
//
//timer1
//
this->timer1->AutoSize = true;
this->timer1->ForeColor = System::Drawing::Color::White;
this->timer1->Location = System::Drawing::Point(253, 108);
this->timer1->Name = L"Timer1";
this->timer1->Size = System::Drawing::Size(34, 13);
this->timer1->TabIndex = 9;
this->timer1->Text = L"00.00";
//
// cooldowns
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->BackColor = System::Drawing::Color::FromArgb(static_cast<System::Int32>(static_cast<System::Byte>(64)), static_cast<System::Int32>(static_cast<System::Byte>(64)),
static_cast<System::Int32>(static_cast<System::Byte>(64)));
this->ClientSize = System::Drawing::Size(294, 138);
this->Controls->Add(this->Timer1);;
this->Controls->Add(this->timer1Progress);
this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::None;
this->Name = L"cooldowns";
this->StartPosition = System::Windows::Forms::FormStartPosition::Manual;
this->Text = L"cooldowns";
this->TopMost = true;
this->Load += gcnew System::EventHandler(this, &cooldowns::cooldowns_Load);
this->ResumeLayout(false);
this->PerformLayout();
}
#pragma endregion
private: System::Void cooldowns_Load(System::Object^ sender, System::EventArgs^ e) {
}
};
}
edit after a lot of trial and error the issue seems to surround the CDwin->Show();. if i switch it to ShowDialog(); it no longer is unresponsive, unfortunately the values of the progress bars do not update either, which i believe is where the multi-threading comes into play.
I think you should use ShowDialog so your form has a message loop, and put your "every 50 ms" stuff in an event handler listening to your timer's Tick event.
As the first form you should always use System::Windows::Forms::Application::Run(CDwin), you can only use Show() and ShowDialog() methods when you already have run a form.
if you use Run() you will encounter some problems. This functions only returns something after form is closed that means codes after the Run() code will not be run until form is closed.
So you must forget about working with your form in main function. I recommend you to create two forms for example "Form1" and "Form2" (using threads is another way but this one's easier).
Use "Form1" as the base form that is hidden and it is used for updating the application by refreshing timer.
Use "Form2" as showed form to user. For doing this you should run "Form2" inside "Form1" using Show() or ShowDialog().
So that means:
// This is Form1 or base.
#include "Form2.h"
Form2 ^openForm2 = gcnew Form2();
openForm2->Show();
// while(true) Refresh the other form and other codes...
I am trying to write a program that uses a global vector of a struct in a c++ windows form. Below is the code. The commented areas are attempts I've made to create a vector. Most of them do not compile. Some of them compile, but the program will not display. I do not understand the nature of this error because I was able to create vectors of structs in command line programs. Any help would be appreciated!
#pragma once
#include <vector>
#include <cliext/vector>
namespace student_database {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
/// <summary>
/// Summary for Form11
/// </summary>
public ref class Form11 : public System::Windows::Forms::Form
{
public:
Form11(void)
{
InitializeComponent();
//
//TODO: Add the constructor code here
//
}
protected:
/// <summary>
/// Clean up any resources being used.
/// </summary>
~Form11()
{
if (components)
{
delete components;
}
}
private:
ref struct student{
int index;
String^ name;
cliext::vector <String^> essays;
};
cliext::vector <student^> student_vector; // builds without errors, but program does not start
// array <student^>^ Qarray;
// static cliext::vector<student^>::generic_container^ student_vector = gcnew cliext::vector<student^>;//(0);
// cliext::vector<student^> ^c;
// c = gcnew(cliext::vector<student^>);
//cliext::vector <student> student_vector = gcnew cliext::vector <student>;
//cliext::vector<student^> ^student_vector = gcnew(cliext::vector<student^>);
// cliext::vector <student^>^ student_vector;
// Microsoft::VisualC::StlClr::Ivector<student^> ^student_vector;
// Ivector<student^> ^student_vector;
/// <summary>
/// Required designer variable.
/// </summary>
System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
this->SuspendLayout();
//
// Form11
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(284, 262);
this->Name = L"Form11";
this->Text = L"Form11";
this->Load += gcnew System::EventHandler(this, &Form11::Form11_Load);
this->ResumeLayout(false);
}
#pragma endregion
private: System::Void Form11_Load(System::Object^ sender, System::EventArgs^ e) {
}
};
}
I have created dialog in .dll project. Now I want to open that dialog from WPF application by clicking on button. Following is the code for dialog:
TestDialog.h:
class CTestDialog : public CDialogEx
{
DECLARE_DYNAMIC(CTestDialog)
public:
CTestDialog(CWnd* pParent = NULL); // standard constructor
virtual ~CTestDialog();
// Dialog Data
enum { IDD = 1000 };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
DECLARE_MESSAGE_MAP()
};
TestDialog.cpp:
#include "stdafx.h"
#include "MFCDll.h"
#include "TestDialog.h"
#include "afxdialogex.h"
IMPLEMENT_DYNAMIC(CTestDialog, CDialogEx)
CTestDialog::CTestDialog(CWnd* pParent /*=NULL*/)
: CDialogEx(CTestDialog::IDD, pParent)
{
}
CTestDialog::~CTestDialog()
{
}
void CTestDialog::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CTestDialog, CDialogEx)
END_MESSAGE_MAP()
I have created export function which create object of dialog and open that dialog by calling the DoModel() function.
extern "C" void PASCAL EXPORT ShowDialogFromDLL()
{
CTestDialog dlg;
theApp.m_pMainWnd = &dlg;
dlg.DoModal();
}
After that I am calling this export function from WPF form following is the code for WPF Form.
MainWindow.xaml.vb:
namespace MainApp
{
public partial class MainWindow : Window
{
[DllImport("MFCDll.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern void ShowDialogFromDLL();
public MainWindow()
{
InitializeComponent();
}
private void btnShow_Click(object sender, RoutedEventArgs e)
{
ShowDialogFromDLL();
}
}
}
But now when I call ShowDialogFromDLL(); after clicking button.It will throw me exception as
Microsoft Visual C++ Debug Library
Debug Assertion Failed!
Program: E:\EDR1\Test\MainApp\bin\Debug\MainApp.vshost.exe
File: f:\dd\vctools\vc7libs\ship\atlmfc\include\afxwin1.inl
Line: 24
For information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts.
(Press Retry to debug the application)
Above error is coming when I call dlg.DoModal(); method.
This should work -
extern "C" __declspec(dllexport) void __stdcall ShowDialogFromDLL()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState())
CTestDialog dlg;
dlg.DoModal();
}
When building a regular DLL that dynamically links to MFC, you need to use the macro AFX_MANAGE_STATE to switch the MFC module state correctly.
i could run the How To Play a File code sample in c++ win32 console application, but when i try to implement it by winforms i get these Link errors:
Error 2 error LNK2020: unresolved token (0A000016) IID_IMediaEvent
Error 3 error LNK2020: unresolved token (0A000017) IID_IMediaControl
and some more link errors .....
here is the code of the form:
#include <dshow.h>
#pragma comment(lib, "Strmiids.lib")
namespace Form1 {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
/// <summary>
/// Summary for Form1
/// </summary>
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
//
//TODO: Add the constructor code here
//
}
protected:
/// <summary>
/// Clean up any resources being used.
/// </summary>
~Form1()
{
if (components)
{
delete components;
}
}
private:
/// <summary>
/// Required designer variable.
/// </summary>
System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
this->SuspendLayout();
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(284, 262);
this->Name = L"Form1";
this->Text = L"Form1";
this->Load += gcnew System::EventHandler(this, &Form1::Form1_Load);
this->ResumeLayout(false);
}
#pragma endregion
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e)
{
IGraphBuilder *pGraph = NULL;
IMediaControl *pControl = NULL;
IMediaEvent *pEvent = NULL;
// Initialize the COM library.
HRESULT hr = CoInitialize(NULL);
// Create the filter graph manager and query for interfaces.
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
IID_IGraphBuilder, (void **)&pGraph);
hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);
// Build the graph. IMPORTANT: Change this string to a file on your system.
hr = pGraph->RenderFile(L"C:\\Example.avi", NULL);
if (SUCCEEDED(hr))
{
// Run the graph.
hr = pControl->Run();
if (SUCCEEDED(hr))
{
// Wait for completion.
long evCode;
pEvent->WaitForCompletion(INFINITE, &evCode);
// Note: Do not use INFINITE in a real application, because it
// can block indefinitely.
}
}
pControl->Release();
pEvent->Release();
pGraph->Release();
CoUninitialize();
}
};
}
How can i setup the build environment in winforms to do the DirectShow programming?
im using windows SDK v7.1 And vc++ 2010
You are not getting a great diagnostic. The problem is that DirectShow is native code. But you are letting the compiler think it is okay to compile it in managed mode. Which works surprisingly well, until the linker takes a nosedive. You need to make it look like this:
#pragma once
#pragma managed(push, off)
#include <dshow.h>
#pragma managed(pop)
#pragma comment(lib, "strmiids.lib")
#pragma comment(lib, "ole32.lib")
// etc..
This probably generates a flurry of errors. Right-click the project in the Solution Explorer window, Properties, Configuration Properties, General. Change Common Language Runtime support from /clr:pure to /clr. This played a sample .avi file properly when I tried it. In a DirectShow window, not the form. The sample code was designed only to work in a console application. You should also remove the calls to CoInitialize and CoUninitialize, .NET already initializes COM. Improving the error handling is advisable. Consider embedding Windows Media Player instead.