I select an image using the CMFCEditBrowseCtrl which has the name:
D:\WhatsApp Image 2020-04-02 at 13.03.48.jpeg
So it is now selected in the control:
Now, I decide to hit the Browse button again:
See?
D:\WhatsApp Image 2020-04-02 at 13.03.48.jpeg appears to be truncated to to at 13.03.48.jpeg. But the moment I click the mouse into the filename control it then shows correct:
It doesn't always show the full name again if you click the edit box. But guaranteed, if you click OK it will be correct and complete.
This is going to be confusing for the user.
Update 1
If I click in the filename and click the HOME button on the keyboard then the rest of the file name comes into view.
Update 2
I have delved into the MFC source code for this bit and this is what it looks like:
case BrowseMode_File:
{
CString strFile;
GetWindowText(strFile);
if (!strFile.IsEmpty())
{
TCHAR fname [_MAX_FNAME];
_tsplitpath_s(strFile, NULL, 0, NULL, 0, fname, _MAX_FNAME, NULL, 0);
CString strFileName = fname;
strFileName.TrimLeft();
strFileName.TrimRight();
if (strFileName.IsEmpty())
{
strFile.Empty();
}
const CString strInvalidChars = _T("*?<>|");
if (strFile.FindOneOf(strInvalidChars) >= 0)
{
if (!OnIllegalFileName(strFile))
{
SetFocus();
return;
}
}
}
CFileDialog dlg(TRUE, !m_strDefFileExt.IsEmpty() ? (LPCTSTR)m_strDefFileExt : (LPCTSTR)NULL, strFile, m_dwFileDialogFlags, !m_strFileFilter.IsEmpty() ? (LPCTSTR)m_strFileFilter : (LPCTSTR)NULL, NULL);
if (dlg.DoModal() == IDOK && strFile != dlg.GetPathName())
{
SetWindowText(dlg.GetPathName());
SetModify(TRUE);
OnAfterUpdate();
}
if (GetParent() != NULL)
{
GetParent()->RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
}
}
break;
}
Update 3
I have tried to roll out my own class that overrides the OnBrowse handler. It has improved logic for setting the default filter index and default file extension:
#include "stdafx.h"
#include "MyMFCEditBrowseFileCtrl.h"
IMPLEMENT_DYNAMIC(CMyMFCEditBrowseFileCtrl, CMFCEditBrowseCtrl)
BEGIN_MESSAGE_MAP(CMyMFCEditBrowseFileCtrl, CMFCEditBrowseCtrl)
END_MESSAGE_MAP()
void CMyMFCEditBrowseFileCtrl::OnBrowse()
{
CString strFile, strFileExtension;
GetWindowText(strFile);
if (!strFile.IsEmpty())
{
TCHAR fname[_MAX_FNAME];
TCHAR ext[_MAX_EXT];
_tsplitpath_s(strFile, NULL, 0, NULL, 0, fname, _MAX_FNAME, ext, _MAX_EXT);
CString strFileName = fname;
strFileName.TrimLeft();
strFileName.TrimRight();
if (strFileName.IsEmpty())
{
strFile.Empty();
}
strFileExtension = ext;
strFileExtension.Trim();
strFileExtension.MakeLower();
const CString strInvalidChars = _T("*?<>|");
if (strFile.FindOneOf(strInvalidChars) >= 0)
{
if (!OnIllegalFileName(strFile))
{
SetFocus();
return;
}
}
}
int iFilterIndex = 2; // jpg - fallback
m_strDefFileExt = _T("jpg");
if (strFileExtension == _T(".gif"))
{
iFilterIndex = 1;
m_strDefFileExt = _T("gif");
}
else if (strFileExtension == _T(".jpeg") || strFileExtension == _T(".jpg"))
{
iFilterIndex = 2;
m_strDefFileExt = _T("jpg");
}
else if (strFileExtension == _T(".png"))
{
iFilterIndex = 3;
m_strDefFileExt = _T("png");
}
else if (strFileExtension == _T(".tif") || strFileExtension == _T(".tiff"))
{
iFilterIndex = 4;
m_strDefFileExt = _T("tif");
}
else if (strFileExtension == _T(".bmp"))
{
iFilterIndex = 5;
m_strDefFileExt = _T("bmp");
}
CFileDialog dlg(TRUE, (LPCTSTR)m_strDefFileExt,
strFile,
m_dwFileDialogFlags,
!m_strFileFilter.IsEmpty() ? (LPCTSTR)m_strFileFilter : (LPCTSTR)NULL, NULL);
dlg.m_pOFN->nFilterIndex = iFilterIndex;
if (dlg.DoModal() == IDOK && strFile != dlg.GetPathName())
{
SetWindowText(dlg.GetPathName());
SetModify(TRUE);
OnAfterUpdate();
}
if (GetParent() != NULL)
{
GetParent()->RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
}
}
But, it still have this odd behaviour I described.
Update 4
This issue is technically related to CFileDialog. If I simply try:
CFileDialog dlgOpen(TRUE, _T("MWB"), _T("123456789abcdefghijklmnopqrstuvwxyz.mwb"), OFN_PATHMUSTEXIST | OFN_HIDEREADONLY, strFilter, this);
Then all that is visibly selected is "rstuvwxyz.mwb".
Update 5
One of the replies here states:
This really isn't an MFC issue. The bad actor is the shell's COM object that implements the IFileDialog interface that is used by MFC under the hood. The following minimal example reproduces the problem using COM without any MFC code.
#include <Windows.h>
#include <ShlObj.h>
int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE hPrevious, LPWSTR szCommandline, INT nShow)
{
HRESULT hr = CoInitialize(nullptr);
if (SUCCEEDED(hr))
{
IFileDialog *pfd = nullptr;
hr = CoCreateInstance(CLSID_FileOpenDialog,
nullptr,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&pfd));
if (SUCCEEDED(hr))
{
COMDLG_FILTERSPEC rgFileSpec[] = {
{L"MWB Files (*.mwb)", L"*.mwb"},
{L"All Files (*.*)", L"*.*"}
};
hr = pfd->SetFileTypes(ARRAYSIZE(rgFileSpec), rgFileSpec);
hr = pfd->SetFileName(L"123456789abcdefghijklmnopqrstuvwxyz.mwb");
hr = pfd->Show(NULL);
pfd->Release();
}
}
CoUninitialize();
return 0;
}
This class solves it
FileDialogHack.h:
#pragma once
#include <afxdlgs.h>
/////////////////////////////////////////////////////////////////////////////
// CFileDialogHack dialog
//
// solves bug in filedialog:
// https://developercommunity.visualstudio.com/t/problem-with-using-the-cfiledialog-class/1225634
//
class CFileDialogHack : public CFileDialog
{
public:
CFileDialogHack(BOOL bOpenFileDialog, LPCTSTR lpszDefExt = NULL, LPCTSTR lpszFileName = NULL,
DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
LPCTSTR lpszFilter = NULL, CWnd* pParentWnd = NULL);
virtual INT_PTR DoModal();
protected:
HWINEVENTHOOK wineventhook();
public:
void _WinEventProcCallback(HWINEVENTHOOK hWinEventHook,
DWORD dwEvent, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime);
LRESULT _CallWndProc(int code, WPARAM wParam, LPARAM lParam);
protected:
HWINEVENTHOOK m_hHook;
HHOOK m_hWndProcHook;
HWND m_hDialog;
HWND m_hCombo;
HWND m_hEdit;
BOOL m_bHook;
HWND m_hParent;
};
FileDialogHack.cpp:
#include "stdafx.h"
#include "FileDialogHack.h"
/////////////////////////////////////////////////////////////////////////////
// CMyFileDialogHack dialog
static CFileDialogHack* g_ptrfiledaloghack = nullptr;
CFileDialogHack::CFileDialogHack(BOOL bOpenFileDialog, LPCTSTR lpszDefExt, LPCTSTR lpszFileName,
DWORD dwFlags, LPCTSTR lpszFilter, CWnd* pParentWnd)
: CFileDialog(bOpenFileDialog, lpszDefExt, lpszFileName, dwFlags, lpszFilter, pParentWnd, 0, TRUE),
m_hHook(0), m_hWndProcHook(0), m_hParent(0), m_hDialog(0), m_hCombo(0), m_hEdit(0), m_bHook(0)
{
}
LRESULT CFileDialogHack::_CallWndProc(int code, WPARAM wParam, LPARAM lParam)
{
PCWPRETSTRUCT data = (PCWPRETSTRUCT)lParam;
if (data->hwnd == m_hCombo && data->message == CBEM_GETEDITCONTROL)
{
m_hEdit = (HWND)data->lResult;
return CallNextHookEx(0, code, wParam, lParam);
}
if (m_bHook)
{
if (data->hwnd == m_hEdit && data->message == EM_SETSEL &&
data->wParam == 0 && data->lParam == -1)
::SendMessage(m_hEdit, EM_SETSEL, (WPARAM)0, (LPARAM)0);
else if (data->hwnd == m_hParent && data->message == WM_ENTERIDLE)
{
m_bHook = 0;
TCHAR text[MAX_PATH];
::GetWindowText(m_hEdit, text, MAX_PATH - 1);
auto len = _tcslen(text);
::SendMessage(m_hEdit, EM_SETSEL, (WPARAM)0, (LPARAM)0);
::SendMessage(m_hEdit, EM_SETSEL, (WPARAM)0, (LPARAM)len);
::SetFocus(m_hEdit);
}
}
return CallNextHookEx(0, code, wParam, lParam);
}
static LRESULT CALLBACK CallWndProc(int code, WPARAM wParam, LPARAM lParam)
{
if (g_ptrfiledaloghack)
return g_ptrfiledaloghack->_CallWndProc(code, wParam, lParam);
return CallNextHookEx(0, code, wParam, lParam);
}
VOID CALLBACK CFileDialogHack::_WinEventProcCallback(HWINEVENTHOOK /*hWinEventHook*/,
DWORD dwEvent, HWND hwnd, LONG idObject, LONG /*idChild*/,
DWORD /*dwEventThread*/, DWORD /*dwmsEventTime*/)
{
if (idObject == OBJID_WINDOW && dwEvent == EVENT_OBJECT_CREATE)
{
if (IsWindow(hwnd) && ::GetDlgCtrlID(hwnd) == 1148)
{
m_hCombo = hwnd; // We have the file dialog's filename combobox field.
m_hDialog = ::GetParent(hwnd);
m_hParent = ::GetParent(m_hDialog);
m_hEdit = (HWND) ::SendMessage(m_hCombo, CBEM_GETEDITCONTROL, 0, 0);
DWORD threadID = GetWindowThreadProcessId(m_hDialog, NULL);
// Hook messages to the file dialog.
m_hWndProcHook = SetWindowsHookEx(WH_CALLWNDPROCRET, CallWndProc, NULL, threadID);
}
}
}
static VOID CALLBACK WinEventProcCallback(HWINEVENTHOOK hWinEventHook,
DWORD dwEvent, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread,
DWORD dwmsEventTime)
{
if (g_ptrfiledaloghack)
g_ptrfiledaloghack->_WinEventProcCallback(hWinEventHook,
dwEvent, hwnd, idObject, idChild, dwEventThread, dwmsEventTime);
}
HWINEVENTHOOK CFileDialogHack::wineventhook()
{
// Hook creation of the Open File Dialog.
g_ptrfiledaloghack = this;
m_bHook = 1;
return SetWinEventHook(
EVENT_OBJECT_CREATE, EVENT_OBJECT_CREATE,
NULL, WinEventProcCallback, GetCurrentProcessId(), 0,
WINEVENT_OUTOFCONTEXT);
}
INT_PTR CFileDialogHack::DoModal()
{
m_hHook = wineventhook();
auto r = __super::DoModal();
UnhookWinEvent(m_hHook);
UnhookWindowsHookEx(m_hWndProcHook);
g_ptrfiledaloghack = nullptr;
return r;
}
Related
i have been making a program to read the text from a text file on a button click and show it on the edit control. when the button is clicked, the dialog box opens to select the text file and clicking on ok, it should display on edit control but i am not getting the text in proper format.
this is the output : output image from visual studio
#include <windows.h>
const wchar_t g_szClassName[] = { L"myWindowClass" };
#define IDC_MAIN_EDIT 101
#define IDC_MAIN_BUTTON 102
#define IDC_MAIN_BUTTON1 103
BOOL LoadTextFileToEdit(HWND hEdit, LPTSTR pszFileName)
{
HANDLE hFile;
BOOL bSuccess = FALSE;
hFile = CreateFile(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, 0, NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
DWORD dwFileSize;
dwFileSize = GetFileSize(hFile, NULL);
if (dwFileSize != 0xFFFFFFFF)
{
wchar_t* pszFileText;
pszFileText = (wchar_t*)GlobalAlloc(GPTR, dwFileSize + 1);
if (pszFileText != NULL)
{
DWORD dwRead;
if (ReadFile(hFile, (LPVOID)pszFileText, dwFileSize, &dwRead, NULL))
{
pszFileText[dwFileSize] = 0 ; // Add null terminator
if (SetWindowText(hEdit, (LPCWSTR)pszFileText))
bSuccess = TRUE; // It worked!
}
GlobalFree(pszFileText);
}
}
CloseHandle(hFile);
}
return bSuccess;
}
// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
{
HFONT hfont;
HWND hedit,button,btnsave;
hedit = CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", L"My Own Window", WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | ES_AUTOVSCROLL | ES_MULTILINE
, CW_USEDEFAULT, CW_USEDEFAULT, 100, 100, hwnd, (HMENU)IDC_MAIN_EDIT, GetModuleHandle(NULL), NULL);
button = CreateWindowEx(WS_EX_CLIENTEDGE, L"BUTTON", L"Open File", WS_CHILD | WS_VISIBLE|WS_BORDER|WS_TABSTOP
,CW_USEDEFAULT, CW_USEDEFAULT, 50, 20, hwnd, (HMENU)IDC_MAIN_BUTTON, GetModuleHandle(NULL), NULL);
btnsave = CreateWindowEx(WS_EX_CLIENTEDGE, L"BUTTON", L"Save File", WS_CHILD | WS_VISIBLE | WS_EX_STATICEDGE|WS_TABSTOP
, CW_USEDEFAULT, CW_USEDEFAULT, 50, 20, hwnd, (HMENU)IDC_MAIN_BUTTON1, GetModuleHandle(NULL), NULL);
if (hedit == NULL)
{
MessageBox(NULL, L"Could not create edit box", L"Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hfont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
SendMessage(hedit, WM_SETFONT, (WPARAM)hfont, MAKELPARAM(FALSE, 0));
//SetWindowText(button, L"Open File");
//SetWindowText(btnsave, L"Save File");
}
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_MAIN_BUTTON:
{
OPENFILENAME ofn;
wchar_t szFileName[MAX_PATH] = L"";
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn); // SEE NOTE BELOW
ofn.hwndOwner = hwnd;
ofn.lpstrFilter = L"Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0";
ofn.lpstrFile = szFileName;
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
ofn.lpstrDefExt = L"txt";
if (GetOpenFileName(&ofn))
{
// Do something usefull with the filename stored in szFileName
HWND hedit;
hedit = GetDlgItem(hwnd, IDC_MAIN_EDIT);
LoadTextFileToEdit(hedit, szFileName);
}
}
break;
case IDC_MAIN_BUTTON1:
{
OPENFILENAME ofn;
wchar_t szFileName[MAX_PATH] = L"";
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn); // SEE NOTE BELOW
ofn.hwndOwner = hwnd;
ofn.lpstrFilter = L"Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0";
ofn.lpstrFile = szFileName;
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT;
ofn.lpstrDefExt = L"txt";
if (GetOpenFileName(&ofn))
{
// Do something usefull with the filename stored in szFileName
HWND hedit;
hedit = GetDlgItem(hwnd, IDC_MAIN_EDIT);
}
}
break;
default:
break;
}
break;
case WM_SIZE:
{
HWND hEdit,button,btnsave;
RECT rcClient;
GetClientRect(hwnd, &rcClient);
hEdit = GetDlgItem(hwnd, IDC_MAIN_EDIT);
button = GetDlgItem(hwnd, IDC_MAIN_BUTTON);
btnsave = GetDlgItem(hwnd, IDC_MAIN_BUTTON1);
SetWindowPos(hEdit, NULL, 0, 0, rcClient.right, rcClient.bottom-120, SWP_NOZORDER);
SetWindowPos(button, NULL, rcClient.right-200, rcClient.bottom-30, 70, 30, SWP_NOZORDER);
SetWindowPos(btnsave, NULL, rcClient.right - 100, rcClient.bottom - 30, 70, 30, SWP_NOZORDER);
}
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG msg;
//step 1: registering the window class
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hinstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (!RegisterClassEx(&wc))
{
MessageBox(NULL, L"Window Registration failed", L"Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
//step 2: Creating the Window
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,
g_szClassName, L"The title of my window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 300,
NULL, NULL, hinstance, NULL);
if (hwnd == NULL)
{
MessageBox(NULL, L"Window Registration failed", L"Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
//Step-3: the message loop
while (GetMessage(&msg, NULL, 0, 0)>0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
i got the answer to my question. Actually in unicode wide string a character is of 2 bytes so we need to allocate twice the memory. so replace :
pszFileText = (wchar_t*)GlobalAlloc(GPTR, dwFileSize + 1);
with
pszFileText = (wchar_t*)GlobalAlloc(GPTR, 2*(dwFileSize + 1));
and
if (ReadFile(hFile, (LPVOID)pszFileText, dwFileSize, &dwRead, NULL))
with
if (ReadFile(hFile, (LPVOID)pszFileText, 2*(dwFileSize+1), &dwRead, NULL))
I am trying to figure out the exact reason for the crash happening in my 32 bit MFC application which is running on 64 bit system.
Actually this is a multithreaded MFC SDI application and can do cyclic execution which includes Inspection and outputting inspection results as reports.
After an inspection finishes it show a Custom Alert Window with a progress control until the reports are generated.The Alert Window is created from a Worker Thread and the Main Thread waits until the window is created.
Below is the coded representation of one cycle of Displaying the Alert Window With Progress Bar:
static const __int64 POPUPWND_POLLPERIOD = 10 * 10000LL;
static const __int64 POPUPWND_POLLTIMEOUT = 1000 * POPUPWND_POLLPERIOD;
class CCallFunc
{
public:
class Queue;
public:
typedef int(*Call)(const CCallFunc &cf);
public:
CCallFunc(Call call, LPVOID lpData) :
m_call(call),
m_lpData(lpData)
{}
int Run() { m_call(*this); }
LPVOID GetData() const { return m_lpData; }
private:
Call m_call;
LPVOID m_lpData;
};
class CCallFunc::Queue
{
public:
int SetQueue(const CCallFunc &cf, const __int64 &timeout = INFINITE)
{
m_pcf = &cf;
m_timeout = timeout;
}
public:
int Run(const __int64 &timeout = 0)
{
CCallFunc cf(*m_pcf);
cf.Run();
}
private:
const CCallFunc* m_pcf;
__int64 m_timeout;
};
class CWorkThread
{
private:
static DWORD WINAPI SystemThread(LPVOID lpData)
{
CWorkThread* pThread = (CWorkThread*)lpData;
__int64 timeout = pThread->m_timeout;
try {
pThread->m_queue.Run(timeout);
}
catch (const CCallFunc &cf) {
pThread->m_queue.SetQueue(cf, timeout);
}
}
public:
static int Aquire(CWorkThread *pThread)
{
pThread = &thisThread;
return S_OK;
}
static void Sleep(const __int64 &period)
{
__int64 current;
__int64 final = period;
switch (final) {
case INFINITE:
while (true)
::SleepEx(INFINITE, TRUE);
throw;
case 0:
::SleepEx(DWORD(0), TRUE);
return;
default:
::GetSystemTimeAsFileTime(reinterpret_cast<FILETIME*>(¤t));
if ((final += current) < 0)
final = current;
while (current < final) {
if (::SleepEx(DWORD((final - current) / __int64(10000)), TRUE) == 0)
return;
::GetSystemTimeAsFileTime((FILETIME*)¤t);
}
}
}
int Start(CCallFunc::Call call, LPVOID lpData)
{
return Start(CCallFunc(call, lpData));
}
int Start(const CCallFunc &fc)
{
DWORD dwID = 0;
::CreateThread(0, 0, &SystemThread, this, 0, &dwID);
}
public:
CCallFunc::Queue m_queue;
private:
__int64 m_timeout;
static CWorkThread thisThread;
};
class CPopupWindow;
struct PopupWndCreateContext : public CCreateContext {
CPopupWindow* popup;
CString clsname;
CString wndname;
DWORD style;
DWORD exstyle;
CRect rc;
HWND parent;
UINT id;
};
class CPopupWindow : public CWnd
{
public:
int Show()
{
HWND hParent = 0;
CWinApp* pApp = NULL;
CWnd* pMain;
if ((pApp = ::AfxGetApp()) != 0 && (pMain = pApp->GetMainWnd()) != 0) {
hParent = pMain->m_hWnd;
}
Create(800, 600, hParent);
}
private:
int Create(int iWidth, int iHeight, HWND parent)
{
PopupWndCreateContext ctxt;
ctxt.popup = this;
ctxt.clsname = "AlertCtrl";
ctxt.wndname = "Alert Control";
ctxt.style = WS_VISIBLE | WS_POPUP;
ctxt.exstyle = 0;
ctxt.rc = CRect(0, 0, iWidth, iHeight);
ctxt.parent = parent;
ctxt.id = 10000;
CWorkThread* pThread;
int e;
if (SUCCEEDED(e = CWorkThread::Aquire(pThread)) && SUCCEEDED(e = pThread->Start(&Run, &ctxt))) {
for (__int64 t = 0; t < POPUPWND_POLLTIMEOUT; t += POPUPWND_POLLPERIOD) {
if (::IsWindow(*this))
return 0;
CWorkThread::Sleep(POPUPWND_POLLPERIOD);
}
}
}
static int Run(const CCallFunc &cf)
{
int e = 0;
PopupWndCreateContext& ctxt = *(static_cast<PopupWndCreateContext*>(cf.GetData()));
ASSERT(&ctxt != 0);
CPopupWindow &wnd = *ctxt.popup;
static const DWORD clsstyle = CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW;
static const HCURSOR clscursor = ::LoadCursor(0, IDC_WAIT);
static const HICON clsicon = 0;
static LPCTSTR clsname = ::AfxRegisterWndClass(clsstyle, clscursor, NULL, clsicon);
if (wnd.CreateEx(DWORD(ctxt.exstyle), ctxt.clsname, ctxt.wndname, DWORD(ctxt.style), ctxt.rc.left, ctxt.rc.top, ctxt.rc.Width(), ctxt.rc.Height(), ctxt.parent, HMENU(ctxt.id), 0) != 0) {
HWND hwnd = wnd.GetSafeHwnd();
::UpdateWindow(hwnd);
MSG msg;
while ((::GetMessage(&msg, 0, 0, 0))) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
wnd.DestroyWindow();
}
return e;
}
};
class CAlertCtrl : CPopupWindow
{
CProgressCtrl m_progctrl;
DECLARE_MESSAGE_MAP();
int OnCreate(LPCREATESTRUCT cs)
{
int e = 0; //< error code / return value
if ((e = __super::OnCreate(cs)) != 0)
return e;
if (!::IsWindow(m_progctrl))
{
CRect rc;
GetClientRect(rc);
if (m_progctrl.Create(WS_CHILD | WS_VISIBLE | PBS_SMOOTH, rc, this, 100000))
m_progctrl.SetRange(0, 10000);
}
return e;
}
};
BEGIN_MESSAGE_MAP(CAlertCtrl, CPopupWindow)
ON_WM_CREATE()
END_MESSAGE_MAP()
So while executing m_progctrl.Create it crashes in the Wincore.cpp
at the method CWnd::DefWindowProc trying to execute callWindowProc after calling the method CPopupWindow::Show for the 35th Cycle.
/////////////////////////////////////////////////////////////////////////////
// Default CWnd implementation
LRESULT CWnd::DefWindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam)
{
if (m_pfnSuper != NULL)
return ::CallWindowProc(m_pfnSuper, m_hWnd, nMsg, wParam, lParam);
I am trying to compile my Win32, OpenGL program in visual studio 2012 and I keep getting this error:
Error 1 error LNK2019: unresolved external symbol __imp__glClear#4 referenced in function _WinMain#16 C:\Users\Chief\Documents\Programming\C++\Projects\Practice\Practice\WinMain.obj Practice
Error 2 error LNK1120: 1 unresolved externals C:\Users\Chief\Documents\Programming\C++\Projects\Practice\Debug\Practice.exe 1 1 Practice
Here is my code:
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <gl/GL.h>
HWND hwnd;
int clientWidth = 800;
int clientHeight = 600;
bool InitMainWindow(HINSTANCE hInstance);
LRESULT CALLBACK MsgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
if(!InitMainWindow(hInstance))
{
return 1;
}
MSG msg = {0};
while(WM_QUIT != msg.message)
{
if(PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//This is where all my updating and rendering stuff will go
}
}
return static_cast<int>(msg.wParam);
}
bool InitMainWindow(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
ZeroMemory(&wcex, sizeof(WNDCLASSEX));
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.hInstance = hInstance;
wcex.lpfnWndProc = MsgProc;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wcex.lpszClassName = "Project2DClass";
wcex.lpszMenuName = NULL;
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wcex))
{
MessageBox(NULL, "Failed to register window class", NULL, NULL);
return false;
}
RECT r = { 0, 0, clientWidth, clientHeight };
DWORD style = WS_OVERLAPPEDWINDOW;
AdjustWindowRect(&r, style, false);
int width = r.right - r.left;
int height = r.bottom - r.top;
int x = GetSystemMetrics(SM_CXSCREEN)/2 - width/2;
int y = GetSystemMetrics(SM_CYSCREEN)/2 - height/2;
hwnd = CreateWindow("Project2DClass", "Project 2D", style, x, y, width, height, NULL, NULL, hInstance, NULL);
if(!hwnd)
{
MessageBox(NULL, "Failed to create window", NULL, NULL);
return false;
}
ShowWindow(hwnd, SW_SHOW);
return true;
}
LRESULT CALLBACK MsgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
Can someone tell me how I can resolve this and what I have done wrong? And once again I am using microsoft visual studio 2012 and openGL
you are missing one or more libraries at the link step: OpenGL32.lib
You need to do the following
Add "opengl32.lib " to Project Properties->Configuration Properties->Linker->Input->Additional Dependencies.
You need to link to the opengl32 library, probably just opengl32.lib.
See also the documentation (but remember this is technically written for OpenGL 1.1 which MS supports, any newer functionality will need to be catered for in some other way, like GLEW, GLUT, etc...)
for the 1120 error i recommend seeing this link: C++ Fatal Error LNK1120: 1 unresolved externals
for 2019 :http://msdn.microsoft.com/en-us/library/799kze2z%28v=vs.80%29.aspx
I am at a loss as to why I am getting this error:
test_project.obj : error LNK2019: unresolved external symbol "int __cdecl run(void)" (?run##YAHXZ) referenced in function _WinMain#16
code is as follows:
#include "stdafx.h"
#include "test_project.h"
#include <Windows.h>
HWND ghMainWnd = 0;
bool InitWindowsApp (HINSTANCE instanceHandle, int show);
int run();
LRESULT CALLBACK
WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
int WINAPI
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pCmdLine, int nShowCmd) {
if (!InitWindowsApp (hInstance, nShowCmd) )
return 0;
return run();
}
bool InitWindowsApp (HINSTANCE instanceHandle, int show) {
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = instanceHandle;
wc.hIcon = LoadIcon( 0, IDI_APPLICATION );
wc.hCursor = LoadCursor( 0 , IDC_ARROW );
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = L"BasicWndClass";
if (!RegisterClass(&wc) ) {
MessageBox(0, L"RegisterClass FAILED", 0, 0);
return false;
}
ghMainWnd = CreateWindow (
L"BasicWndClass",
L"Win32Basic",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
0,
0,
instanceHandle,
0);
if (ghMainWnd == 0) {
MessageBox ( 0, L"CreateWindow FAILED", 0, 0);
return false;
}
ShowWindow (ghMainWnd, show);
UpdateWindow (ghMainWnd);
return true;
}
int Run() {
MSG msg = {0};
BOOL bRet = 1;
while ((bRet = GetMessage(&msg, 0, 0, 0)) != 0) {
if (bRet == -1)
{
MessageBox(0, L"GetMessage FAILED", L"Error", MB_OK);
break;
}
else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int)msg.wParam;
}
LRESULT CALLBACK
WndProc ( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch(msg) {
case WM_LBUTTONDOWN:
MessageBox(0, L"Hello, World", L"Hello", MB_OK);
return 0;
case WM_KEYDOWN:
if (wParam == VK_ESCAPE)
DestroyWindow(ghMainWnd);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc (hWnd, msg, wParam, lParam);
}
In the property pages->c/c++->general->additional include directories I have put the directory containing the lib: C:\Program Files\Microsoft SDKs\Windows\v7.1\Lib
In property pages->linker->input->additional dependencies I have put the full path to the lib C:\Program Files\Microsoft SDKs\Windows\v7.1\Lib\user32.lib
In property pages->linker->system->subsystem I have put Windows (/SUBSYSTEM:WINDOWS)
I am at a loss as to what to try next.
C++ is case-sensitive. You have to decide whether to name your function run() or Run().
int run();
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR pCmdLine, int nShowCmd) {
if (!InitWindowsApp (hInstance, nShowCmd) )
return 0;
return run(); // <-- There.
}
Versus:
int Run() {
// ...
}
I am working with vb.net .. I am new in vc++. I need to write some code in vc++ in some case. I need vc++ for following reason.
I created one dll in vb.net and make a tlb file based on vb.net dll. I import physical tlb file in my vc++ code with static value, as mentioned following.
#import "C:\Documents and Settings\Ankit.ass\My Documents\Visual Studio 2010\Projects\SetupValidationPro\SetupValidationPro\bin\Debug\SetupValidationPro.tlb" named_guids raw_interfaces_only
That's work fine.. My problem is that, I want to create a tlb file dynamically or runtime using vc++ and load that tlb file dynamically.
So, I need to embed a dll in vc++. How can I embed dll in vc++?
Now, I want to extract my embed dll to some physical file. so how can I extract my dll to physical location in vc++?
And, at the last step I want to create a tlb file dynamically using that extracted dll using vc++.. and load tlb file dynamically.
How can I achieve this?
Thanks
Ankit
I resolve the issue after lots of googling.. This is the code from where my issue is resolve. I don't need native code for this..
#include "stdafx.h"
#include "stdafx.h"
#include <Msi.h>
#include <WinUser.h>
#include "windows.h"
#include <afxwin.h>
#include <afx.h>
#include <WinSpool.h>
#include <assert.h>
#include <WinBase.h>
#include "resource.h"
#define IDR_DLL1 101
#define IDR_EXE1 102
bool ExtractDll(const HINSTANCE hInstance, WORD resourceID, LPCTSTR szOutputFilename);
bool ExtractExe(const HINSTANCE hInstance, WORD resourceID, LPCTSTR szOutputFilename);
bool cmd();
CString AppPath();
#define RtlCopyMemory(Destination,Source,Length) memcpy((Destination),(Source),(Length))
#import "dv.tlb" named_guids raw_interfaces_only
using namespace dv;
UINT __stdcall Validation( MSIHANDLE hModule )
{
/*BOOL qw = ExtractDll(AfxGetResourceHandle(), IDR_DLL1, _T("C:\\VBDLL.dll") );
BOOL qw1 = ExtractExe(AfxGetResourceHandle(), IDR_EXE1, _T("C:\\RegAsm.exe") );*/
BOOL qw = ExtractDll(AfxGetResourceHandle(), IDR_DLL1, (LPCTSTR)(AppPath() + _T("\\dv.dll")) );
if (qw == false)
{
return ERROR_INSTALL_USEREXIT;
}
BOOL qw1 = ExtractExe(AfxGetResourceHandle(), IDR_EXE1, (LPCTSTR)(AppPath() + _T("\\RegAsm.exe")) );
if (qw1 == false)
{
return ERROR_INSTALL_USEREXIT;
}
BOOL retCmd = cmd();
if (retCmd==false)
{
return ERROR_INSTALL_USEREXIT;
}
IkeyvalidationPtr pICalc(__uuidof(SetupClass));
long retun =0;
BSTR strVer = SysAllocString(L"4.0.1517");
pICalc->keyValidation(strVer,&retun);
if (retun==1)
{
return ERROR_INSTALL_USEREXIT;
}
return ERROR_SUCCESS;
}
CString AppPath()
{
try
{
TCHAR path [MAX_PATH];
ITEMIDLIST* pidl;
HRESULT hRes = SHGetSpecialFolderLocation( NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE , &pidl );
if (hRes==NOERROR)
{
SHGetPathFromIDList( pidl, path);
}
CString apPath;
apPath = path;
apPath = apPath + _T("\\path");
CreateDirectory((LPCWSTR) apPath,NULL);
return apPath;
}
catch(...)
{
}
}
bool cmd()
{
CString m1=_T('');
CString temp1 = _T("");
CString temp = temp1 + _T('"');
//CString s1 = temp + AppPath() + _T("\\RegAsm.exe"); // Cascading concatenation
CString s1 = temp + AppPath() + _T("\\RegAsm.exe") + _T('"'); // Cascading concatenation
CString s2 = _T(" /codebase");
CString message = s1 + _T('"')+ _T(' ')+ _T('"') + AppPath() + _T("\\dv.dll") + _T('"') +_T(' ') + _T("/tlb:")+('"') + AppPath() + _T("\\dv.tlb") + _T('"')+ s2;
CString message1 = _T('"') + AppPath() + _T("\\dv.dll") + _T('"') +_T(' ') + _T("/tlb:")+('"') + AppPath() + _T("\\dv.tlb") + _T('"')+ s2;
SHELLEXECUTEINFO ExecuteInfo;
memset(&ExecuteInfo, 0, sizeof(ExecuteInfo));
ExecuteInfo.cbSize = sizeof(ExecuteInfo);
ExecuteInfo.fMask = 0;
ExecuteInfo.hwnd = 0;
ExecuteInfo.lpVerb = L"runas"; // Operation to perform
ExecuteInfo.lpFile = s1;
ExecuteInfo.lpParameters = message1; // Additional parameters
ExecuteInfo.lpDirectory = 0; // Default directory
ExecuteInfo.nShow = SW_HIDE;
//ExecuteInfo.nShow = SW_SHOW;
ExecuteInfo.hInstApp = 0;
if(ShellExecuteEx(&ExecuteInfo) == FALSE)
{
return false;
}
return true;
}
bool ExtractDll(const HINSTANCE hInstance, WORD resourceID, LPCTSTR szOutputFilename)
{
TCHAR sResName[5] = _T("#101");
TCHAR sRestype[4] = _T("DLL");
HRSRC hres = FindResource(AfxGetResourceHandle(), sResName,sRestype);
if (hres == 0)
{
return false;
}
HGLOBAL hbytes = LoadResource(hInstance, hres);
// Lock the resource
LPVOID pdata = LockResource(hbytes);
DWORD dwSize = SizeofResource(hInstance, hres);
HANDLE hFile = CreateFile(szOutputFilename, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
/// INSERT DATA IN FILE
HANDLE hFilemap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, dwSize, NULL);
LPVOID lpBaseAddress = MapViewOfFile(hFilemap, FILE_MAP_WRITE, 0, 0, 0);
try
{
RtlCopyMemory(lpBaseAddress,pdata,dwSize);
}
catch ( ... )
{
return false;
}
UnmapViewOfFile(lpBaseAddress);
CloseHandle(hFilemap);
CloseHandle(hFile);
return true ;
}
bool ExtractExe(const HINSTANCE hInstance, WORD resourceID, LPCTSTR szOutputFilename)
{
/*LPTSTR sArgv = argv[1];
LPTSTR sArgv2 = argv[2];*/
TCHAR sResName[5] = _T("#102");
TCHAR sRestype[4] = _T("EXE");
//HINSTANCE Nl=AfxGetInstanceHandle();
HRSRC hres = FindResource(AfxGetResourceHandle(), sResName, sRestype);
if (hres == 0)
{
return false;
}
HGLOBAL hbytes = LoadResource(hInstance, hres);
// Lock the resource
LPVOID pdata = LockResource(hbytes);
DWORD dwSize = SizeofResource(hInstance, hres);
HANDLE hFile = CreateFile(szOutputFilename, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
/// INSERT DATA IN FILE
HANDLE hFilemap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, dwSize, NULL);
LPVOID lpBaseAddress = MapViewOfFile(hFilemap, FILE_MAP_WRITE, 0, 0, 0);
try
{
RtlCopyMemory(lpBaseAddress,pdata,dwSize);
}
catch ( ... )
{
return false;
}
UnmapViewOfFile(lpBaseAddress);
CloseHandle(hFilemap);
CloseHandle(hFile);
return true;
}
This is the MFC code from which solved my issue. This code embeds the resources, extracts the resources and registers the type library at run-time.