如何通过指针获取构造函数中函数 return 值的地址
How to get address of function return value inside constructor via pointer
我试图在构造函数中访问函数的 return 值地址。我有一个指向 class 构造函数的指针,但是我尝试的任何组合都会给我一个错误。通过这个例子,我认为我走上了正确的道路:
graphics.DrawLine(&p_CustomButton->frontPen, 1, 1, objWidth - 1, objWidth - 1);
我了解指针的工作原理,阅读了很多相关内容,我确信这纯粹是关于语法的。我在上面的示例中遇到错误编译器错误 C2276,所以我看了一下 here 但是当我尝试推荐的内容时它也不起作用:
graphics.DrawLine(&CustomButton::frontPen, 1, 1, objWidth - 1, objWidth - 1);
现在的错误是:
Error C2664 'Gdiplus::Status Gdiplus::Graphics::DrawLine(const Gdiplus::Pen ,const Gdiplus::Point &,const Gdiplus::Point &)': cannot convert argument 1 from 'Gdiplus::Pen (__thiscall CustomButton:: )(void)' to 'const Gdiplus::Pen *'
首先它不应该是 void 因为它被声明了(我认为),其次将它声明为 const 也没有帮助。但我发现我走在正确的轨道上,因为编译器不再抱怨无效语法。
在我的研究过程中,我查看了 here, here (here they advice the same as MSDN), here, here(我尝试了所有可能的括号组合,但收效甚微)和更多的页面,我无法比这更进一步(我也尝试使用 '*' 但是这对我来说毫无意义,因为我不想再做一个指针)。
我是C++新手,在这个问题上花了2个多小时。我试图尽可能清楚地描述问题;如果我对 post 这样的问题做错了什么,请告诉我,我会在下一个 post.
中避免它
完整代码:
#include <windows.h>
#include <commctrl.h>
#include <winuser.h>
#include <gdiplus.h>
#include <string.h>
#include "CustomButton.h"
CustomButton::CustomButton()
{
width = 0;
height = 0;
type = 0;
customButton = NULL;
Gdiplus::SolidBrush frontBrush(Gdiplus::Color(255, 160, 160, 160)); // Create a Brush object.
Gdiplus::Pen frontPen(&frontBrush, 1);
}
CustomButton::~CustomButton()
{
if (customButton)
DestroyWindow(customButton);
}
/*set-get functions*/
HWND CustomButton::getButton()
{
return customButton;
}
void CustomButton::DrawRoundRect(HDC hdc, int X, int Y, int RectWidth, int RectHeight, int CornerRadius)
{
Gdiplus::Graphics graphics(hdc);
graphics.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);
Gdiplus::GraphicsPath gfxPath;
gfxPath.AddLine(X + CornerRadius, Y, X + RectWidth - (CornerRadius * 2), Y);
gfxPath.AddArc(X + RectWidth - (CornerRadius * 2), Y, CornerRadius * 2, CornerRadius * 2, 270, 90);
gfxPath.AddLine(X + RectWidth, Y + CornerRadius, X + RectWidth, Y + RectHeight - (CornerRadius * 2));
gfxPath.AddArc(X + RectWidth - (CornerRadius * 2), Y + RectHeight - (CornerRadius * 2), CornerRadius * 2, CornerRadius * 2, 0, 90);
gfxPath.AddLine(X + RectWidth - (CornerRadius * 2), Y + RectHeight, X + CornerRadius, Y + RectHeight);
gfxPath.AddArc(X, Y + RectHeight - (CornerRadius * 2), CornerRadius * 2, CornerRadius * 2, 90, 90);
gfxPath.AddLine(X, Y + RectHeight - (CornerRadius * 2), X, Y + CornerRadius);
gfxPath.AddArc(X, Y, CornerRadius * 2, CornerRadius * 2, 180, 90);
gfxPath.CloseFigure();
graphics.DrawPath(&frontPen, &gfxPath);
graphics.DrawPath(&frontPen, &gfxPath);
}
CustomButton* CustomButton::CreateCustomButton(HINSTANCE hInstance, HWND hwnd, int pos_x, int pos_y, int width, int height, int type)
{
CustomButton * p_CustomButton = new CustomButton;
p_CustomButton->customButton = CreateWindowEx(0, L"BUTTON", L"OK", WS_VISIBLE | WS_CHILD | BS_OWNERDRAW, pos_x, pos_y, width, height, hwnd, (HMENU)1, (HINSTANCE)GetWindowLong(hwnd, GWLP_HINSTANCE), p_CustomButton); //BS_OWNERDRAW allows BN_CLICKED to be registered and specifies that DRAWITEM will create mask for the button
if (p_CustomButton->customButton == NULL)
{
delete p_CustomButton;
MessageBox(NULL, L"Problem creating the Button.", L"Error", 0);
return 0;
}
p_CustomButton->width = width;
p_CustomButton->height = height;
p_CustomButton->type = type;
if (!SetWindowSubclass(p_CustomButton->customButton, CustomButton::CustomButtonProc, 0, (DWORD_PTR)p_CustomButton))
{
delete p_CustomButton;
MessageBox(NULL, L"Problem subclassing the Button.", L"Error", 0);
return 0;
}
return p_CustomButton;
}
LRESULT CALLBACK CustomButton::CustomButtonProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
CustomButton *p_CustomButton = (CustomButton*)dwRefData;
switch (uMsg)
{
case WM_NCDESTROY:
{
RemoveWindowSubclass(hwnd, CustomButton::CustomButtonProc, uIdSubclass);
p_CustomButton->customButton = NULL;
break;
}
case 0x8000: //WM_DRAWITEM
{
LPDRAWITEMSTRUCT lpdis = (DRAWITEMSTRUCT*)lParam; //assigning drawing structure to the control
/* drawing the classic windows button */
SetBkColor(lpdis->hDC, RGB(18, 18, 18)); //background color for the text, which is assigned to the whole button via ETO_OPAQUE in ExtTextOut
ExtTextOut( //assigns graphic properties to the control
lpdis->hDC,
((lpdis->rcItem.right - lpdis->rcItem.left)) / 2, //X position of the text inside, calculated as half the width
((lpdis->rcItem.bottom - lpdis->rcItem.top)) / 2, //Y
ETO_OPAQUE, //ETO_OPAQUE = button will have the color from SetBkColor
&lpdis->rcItem, //pointer to rectangle inside the drawing structure
0, //text inside button
0, //length of the text string
NULL);
lpdis->CtlType = ODT_BUTTON;
lpdis->itemAction = ODA_DRAWENTIRE;
int lineWidth = 2;
int objWidth = 18;
p_CustomButton->DrawRoundRect(lpdis->hDC, 0, 0, 18, 18, 2);
Gdiplus::Graphics graphics(lpdis->hDC);
graphics.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);
switch (p_CustomButton->type)
{
case 1:
{
graphics.DrawLine(&p_CustomButton->frontPen, 1, 1, objWidth - 1, objWidth - 1);
graphics.DrawLine(p_CustomButton->frontPen, 1, objWidth - 1, objWidth - 1, 1);
graphics.DrawLine(p_CustomButton->frontPen, 1, 1, objWidth - 1, objWidth - 1);
graphics.DrawLine(p_CustomButton->frontPen, 1, objWidth - 1, objWidth - 1, 1);
break;
}
case 2:
{
graphics.DrawLine(p_CustomButton->frontPen, 0, 3, objWidth, 3);
break;
}
case 3:
{
graphics.DrawLine(p_CustomButton->frontPen, 0, objWidth - 3, objWidth, objWidth - 3);
break;
}
}
break;
}
case WM_LBUTTONUP:
{
switch (p_CustomButton->type)
{
case 1:
{
SendMessage(GetParent(hwnd), WM_CLOSE, 0, 0);
break;
}
case 2:
{
ShowWindow(GetParent(hwnd), SW_MAXIMIZE);
break;
}
case 3:
{
ShowWindow(GetParent(hwnd), SW_MINIMIZE);
break;
}
}
break;
}
}
return DefSubclassProc(hwnd, uMsg, wParam, lParam);
}
Header:
#ifndef CUSTOMBUTTON_H
#define CUSTOMBUTTON_H
class CustomButton
{
private:
int width;
int height;
int type;
HWND customButton;
const Gdiplus::SolidBrush frontBrush; // Create a Brush object.
const Gdiplus::Pen frontPen;
CustomButton();
void DrawRoundRect(HDC hdc, int X, int Y, int RectWidth, int RectHeight, int CornerRadius);
static LRESULT CALLBACK CustomButtonProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uint_ptr, DWORD_PTR dwRefData);
public:
~CustomButton();
static CustomButton* CreateCustomButton(HINSTANCE hInst, HWND hwnd, int pos_x, int pos_y, int width, int height, int type);
HWND getButton();
};
#endif
你的构造函数有这个:
Gdiplus::SolidBrush frontBrush(Gdiplus::Color(255, 160, 160, 160)); // Create a Brush object.
Gdiplus::Pen frontPen(&frontBrush, 1);
这会在堆栈上创建 frontBrush 和 frontPen,然后立即销毁它们,因为它们的 scope 仅限于构造函数。它们需要是成员变量(如width
、height
等)并且可以在构造函数的序言中构造:
CustomButton::CustomButton()
: frontBrush(Gdiplus::Color(255, 160, 160, 160))
, frontPen(&frontBrush, 1)
{
.
.
.
}
我试图在构造函数中访问函数的 return 值地址。我有一个指向 class 构造函数的指针,但是我尝试的任何组合都会给我一个错误。通过这个例子,我认为我走上了正确的道路:
graphics.DrawLine(&p_CustomButton->frontPen, 1, 1, objWidth - 1, objWidth - 1);
我了解指针的工作原理,阅读了很多相关内容,我确信这纯粹是关于语法的。我在上面的示例中遇到错误编译器错误 C2276,所以我看了一下 here 但是当我尝试推荐的内容时它也不起作用:
graphics.DrawLine(&CustomButton::frontPen, 1, 1, objWidth - 1, objWidth - 1);
现在的错误是:
Error C2664 'Gdiplus::Status Gdiplus::Graphics::DrawLine(const Gdiplus::Pen ,const Gdiplus::Point &,const Gdiplus::Point &)': cannot convert argument 1 from 'Gdiplus::Pen (__thiscall CustomButton:: )(void)' to 'const Gdiplus::Pen *'
首先它不应该是 void 因为它被声明了(我认为),其次将它声明为 const 也没有帮助。但我发现我走在正确的轨道上,因为编译器不再抱怨无效语法。
在我的研究过程中,我查看了 here, here (here they advice the same as MSDN), here, here(我尝试了所有可能的括号组合,但收效甚微)和更多的页面,我无法比这更进一步(我也尝试使用 '*' 但是这对我来说毫无意义,因为我不想再做一个指针)。
我是C++新手,在这个问题上花了2个多小时。我试图尽可能清楚地描述问题;如果我对 post 这样的问题做错了什么,请告诉我,我会在下一个 post.
中避免它完整代码:
#include <windows.h>
#include <commctrl.h>
#include <winuser.h>
#include <gdiplus.h>
#include <string.h>
#include "CustomButton.h"
CustomButton::CustomButton()
{
width = 0;
height = 0;
type = 0;
customButton = NULL;
Gdiplus::SolidBrush frontBrush(Gdiplus::Color(255, 160, 160, 160)); // Create a Brush object.
Gdiplus::Pen frontPen(&frontBrush, 1);
}
CustomButton::~CustomButton()
{
if (customButton)
DestroyWindow(customButton);
}
/*set-get functions*/
HWND CustomButton::getButton()
{
return customButton;
}
void CustomButton::DrawRoundRect(HDC hdc, int X, int Y, int RectWidth, int RectHeight, int CornerRadius)
{
Gdiplus::Graphics graphics(hdc);
graphics.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);
Gdiplus::GraphicsPath gfxPath;
gfxPath.AddLine(X + CornerRadius, Y, X + RectWidth - (CornerRadius * 2), Y);
gfxPath.AddArc(X + RectWidth - (CornerRadius * 2), Y, CornerRadius * 2, CornerRadius * 2, 270, 90);
gfxPath.AddLine(X + RectWidth, Y + CornerRadius, X + RectWidth, Y + RectHeight - (CornerRadius * 2));
gfxPath.AddArc(X + RectWidth - (CornerRadius * 2), Y + RectHeight - (CornerRadius * 2), CornerRadius * 2, CornerRadius * 2, 0, 90);
gfxPath.AddLine(X + RectWidth - (CornerRadius * 2), Y + RectHeight, X + CornerRadius, Y + RectHeight);
gfxPath.AddArc(X, Y + RectHeight - (CornerRadius * 2), CornerRadius * 2, CornerRadius * 2, 90, 90);
gfxPath.AddLine(X, Y + RectHeight - (CornerRadius * 2), X, Y + CornerRadius);
gfxPath.AddArc(X, Y, CornerRadius * 2, CornerRadius * 2, 180, 90);
gfxPath.CloseFigure();
graphics.DrawPath(&frontPen, &gfxPath);
graphics.DrawPath(&frontPen, &gfxPath);
}
CustomButton* CustomButton::CreateCustomButton(HINSTANCE hInstance, HWND hwnd, int pos_x, int pos_y, int width, int height, int type)
{
CustomButton * p_CustomButton = new CustomButton;
p_CustomButton->customButton = CreateWindowEx(0, L"BUTTON", L"OK", WS_VISIBLE | WS_CHILD | BS_OWNERDRAW, pos_x, pos_y, width, height, hwnd, (HMENU)1, (HINSTANCE)GetWindowLong(hwnd, GWLP_HINSTANCE), p_CustomButton); //BS_OWNERDRAW allows BN_CLICKED to be registered and specifies that DRAWITEM will create mask for the button
if (p_CustomButton->customButton == NULL)
{
delete p_CustomButton;
MessageBox(NULL, L"Problem creating the Button.", L"Error", 0);
return 0;
}
p_CustomButton->width = width;
p_CustomButton->height = height;
p_CustomButton->type = type;
if (!SetWindowSubclass(p_CustomButton->customButton, CustomButton::CustomButtonProc, 0, (DWORD_PTR)p_CustomButton))
{
delete p_CustomButton;
MessageBox(NULL, L"Problem subclassing the Button.", L"Error", 0);
return 0;
}
return p_CustomButton;
}
LRESULT CALLBACK CustomButton::CustomButtonProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
CustomButton *p_CustomButton = (CustomButton*)dwRefData;
switch (uMsg)
{
case WM_NCDESTROY:
{
RemoveWindowSubclass(hwnd, CustomButton::CustomButtonProc, uIdSubclass);
p_CustomButton->customButton = NULL;
break;
}
case 0x8000: //WM_DRAWITEM
{
LPDRAWITEMSTRUCT lpdis = (DRAWITEMSTRUCT*)lParam; //assigning drawing structure to the control
/* drawing the classic windows button */
SetBkColor(lpdis->hDC, RGB(18, 18, 18)); //background color for the text, which is assigned to the whole button via ETO_OPAQUE in ExtTextOut
ExtTextOut( //assigns graphic properties to the control
lpdis->hDC,
((lpdis->rcItem.right - lpdis->rcItem.left)) / 2, //X position of the text inside, calculated as half the width
((lpdis->rcItem.bottom - lpdis->rcItem.top)) / 2, //Y
ETO_OPAQUE, //ETO_OPAQUE = button will have the color from SetBkColor
&lpdis->rcItem, //pointer to rectangle inside the drawing structure
0, //text inside button
0, //length of the text string
NULL);
lpdis->CtlType = ODT_BUTTON;
lpdis->itemAction = ODA_DRAWENTIRE;
int lineWidth = 2;
int objWidth = 18;
p_CustomButton->DrawRoundRect(lpdis->hDC, 0, 0, 18, 18, 2);
Gdiplus::Graphics graphics(lpdis->hDC);
graphics.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);
switch (p_CustomButton->type)
{
case 1:
{
graphics.DrawLine(&p_CustomButton->frontPen, 1, 1, objWidth - 1, objWidth - 1);
graphics.DrawLine(p_CustomButton->frontPen, 1, objWidth - 1, objWidth - 1, 1);
graphics.DrawLine(p_CustomButton->frontPen, 1, 1, objWidth - 1, objWidth - 1);
graphics.DrawLine(p_CustomButton->frontPen, 1, objWidth - 1, objWidth - 1, 1);
break;
}
case 2:
{
graphics.DrawLine(p_CustomButton->frontPen, 0, 3, objWidth, 3);
break;
}
case 3:
{
graphics.DrawLine(p_CustomButton->frontPen, 0, objWidth - 3, objWidth, objWidth - 3);
break;
}
}
break;
}
case WM_LBUTTONUP:
{
switch (p_CustomButton->type)
{
case 1:
{
SendMessage(GetParent(hwnd), WM_CLOSE, 0, 0);
break;
}
case 2:
{
ShowWindow(GetParent(hwnd), SW_MAXIMIZE);
break;
}
case 3:
{
ShowWindow(GetParent(hwnd), SW_MINIMIZE);
break;
}
}
break;
}
}
return DefSubclassProc(hwnd, uMsg, wParam, lParam);
}
Header:
#ifndef CUSTOMBUTTON_H
#define CUSTOMBUTTON_H
class CustomButton
{
private:
int width;
int height;
int type;
HWND customButton;
const Gdiplus::SolidBrush frontBrush; // Create a Brush object.
const Gdiplus::Pen frontPen;
CustomButton();
void DrawRoundRect(HDC hdc, int X, int Y, int RectWidth, int RectHeight, int CornerRadius);
static LRESULT CALLBACK CustomButtonProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uint_ptr, DWORD_PTR dwRefData);
public:
~CustomButton();
static CustomButton* CreateCustomButton(HINSTANCE hInst, HWND hwnd, int pos_x, int pos_y, int width, int height, int type);
HWND getButton();
};
#endif
你的构造函数有这个:
Gdiplus::SolidBrush frontBrush(Gdiplus::Color(255, 160, 160, 160)); // Create a Brush object.
Gdiplus::Pen frontPen(&frontBrush, 1);
这会在堆栈上创建 frontBrush 和 frontPen,然后立即销毁它们,因为它们的 scope 仅限于构造函数。它们需要是成员变量(如width
、height
等)并且可以在构造函数的序言中构造:
CustomButton::CustomButton()
: frontBrush(Gdiplus::Color(255, 160, 160, 160))
, frontPen(&frontBrush, 1)
{
.
.
.
}