2017-07-06 12 views
3

Windows APIリソースは、適切に処理されないとメモリリークを引き起こす可能性があります。それがこの問題に当てはまるかどうか、私はそれが関連していると仮定しています。私は問題がどこから来ているのかを示していますが、解決できませんでした。メモリを増やし、GUIを削除する静的なWin32コントロールをホバリングするのはなぜですか?

私は私のクラスに抽象化されたWin32 APIを使用して静的クラスのコントロール、の2種類があります。

Label 
LinkLabel  

問題:私はこれらの2つのコントロールは、Visual Studioの2017年の診断ツールを追加するときは、プロセスメモリを示しています( MB)は、setFont()またはsetHoverColor()のいずれかの行を有効にしたときに3MBから11MBに増加し、最終的にGUIスペースのすべてが消えてしまいます。

このコードは、(3メガバイトは、プロセスメモリ内の同じ一定の速度のまま)結構です:

// Linked Label 
myLinkLabel.init("http://www.google.com", 50, 450); 
myLinkLabel.setColor(0, 0, 255); 
myLinkLabel.onClick(lbl_Click); 
myLinkLabel.setFont("Arial", 40, true); 
//lbl.setHoverColor(255, 0, 0);  

// label 
myLabel.init("A regular static label", 0, 0); 
myLabel.setColor(0, 255, 0); 
myLabel.setFont("Arial", 40); 
//myLabel.setHoverColor(255, 0, 0); 

この次のコードは、最後の行行をコメント。 myLabel上にマウスカーソルを移動すると、赤色のハイライトカラーが表示され、プロセスメモリの3MBが7MB以上に増加します。それはちょっと座ってから、9MB以上になる。だから、何かが間違っている。

// Linked Label 
myLinkLabel.init("http://www.google.com", 50, 450); 
myLinkLabel.setColor(0, 0, 255); 
myLinkLabel.onClick(lbl_Click); 
myLinkLabel.setFont("Arial", 40, true); 
//lbl.setHoverColor(255, 0, 0);  

// label 
myLabel.init("A regular static label", 0, 0); 
myLabel.setColor(0, 255, 0); 
myLabel.setFont("Arial", 48); 
myLabel.setHoverColor(255, 0, 0); 

それでは、私のsetHoverColor()掘り下げてみましょうしない:上記のコードでは、あまりにも素晴らしい

void Label::setHoverColor(const BYTE red, const BYTE blue, const BYTE green) 
{ 
 m_hoverColorEnabled = true; 
 m_hoverColor = RGB(red, green, blue); 
} 

さて、何も。これは私にWndProcを見るように指示します。

この静的コントロールで使用されるイベントは、WM_SETCURSORです。

case WM_SETCURSOR: 
{ 
HWND m_handle = (HWND)wParam; 
// Label 
for (int i = 0; i < frm.getLabelControlCount(); i++) 
{ 
    if (frm.getLabelControl(i).getHandle() == m_handle) 
    { 
      if (frm.getLinkLabelControl(i).isLink()) 
      { 
       // Set hover color to link  
       if (frm.getLabelControl(i).isHoverColorEnabled()) 
         frm.getLabelControl(i).setColor(frm.getLabelControl(i).getHoverColor()); 
         // Update cursor to hand 
         SetClassLongPtr(frm.getLabelControl(i).getHandle(), GCLP_HCURSOR, (LONG_PTR)frm.getLabelControl(i).getHoverCursor()); 
      } 
     } 
     else 
     { 
      // Set link to blue and use default arrow  
      if (frm.getLabelControl(i).isHoverColorEnabled()) 
      frm.getLabelControl(i).setColor(0, 0, 255); 
      SetClassLongPtr(frm.getLabelControl(i).getHandle(), GCLP_HCURSOR, 
     (LONG_PTR)LoadCursor(NULL, IDC_ARROW)); 
     } 
} 

コードのこのセクションをコメント、プロセスメモリは、3メガバイトで一定に留まります。このセクションのコメントを解除すると、プロセスメモリが増加します。これは明らかに問題の原因となっている主なコードです。

このセクションでは、基本的に、現在のマウスのホバー状態に基づいてラベルのテキストの色を更新しています。それは上に乗っていないときは青色で、上に乗ったときは赤色です。

setColorを()次のコードです:

もそれを更新するためのsetFont()を呼び出している
void Label::setColor(const COLORREF color) 
{ 
 m_foreColor = color; 
 setFont(m_fontName, m_fontSize, m_bold, m_italic, m_underlined); 
} 

bool Label::setFont(const std::string &fontName, const int size, const bool bold, 
 const bool italic, const bool underlined) 
{  
 DWORD dwItalic; 
 DWORD dwBold; 
 DWORD dwUnderlined; 
 SIZE linkSize; 
 dwItalic = (italic) ? TRUE : FALSE; 
 dwBold = (bold) ? FW_BOLD : FW_DONTCARE; 
 dwUnderlined = (underlined) ? TRUE : FALSE; 
 m_font = CreateFont(size, 0, 0, 0, dwBold, dwItalic, dwUnderlined, FALSE, 
  ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, 
  DEFAULT_PITCH | FF_SWISS, fontName.c_str()); 
 SendMessage(m_handle, WM_SETFONT, WPARAM(m_font), TRUE); 
  
 // Calculate the correct width and height size  
 HDC hDC = GetDC(m_handle); 
 SelectFont(hDC, m_font); 
 GetTextExtentPoint32(hDC, m_text.c_str(), (int) m_text.length(), &linkSize); 
 setSize(linkSize.cx, size);  
  
 // Store font information 
 m_fontName = fontName; 
 m_fontSize = size; 
 m_bold = bold; 
 m_underlined = underlined; 
 m_italic = italic; 
  
 return true; 
} 

私の推測では、これは、フォントを作成するための更新がたくさんあるさすべてのホバーに基づいて再作成します。私の推論は、フォントを再設定しない限り、フォントの色を更新しないということでした。近いうちにこれのための余地はありますが、ここでリソースや何かを削除するのを忘れていますか?どんな考えも歓迎されます。これがLinkLabelを解決することは間違いありません。

+0

tl;あなたは私の注意を "...よく知られている書店のように"失ってしまった。あなたが話している店舗やその店舗がどのように問題に関連しているのかわからない – user463035818

+0

ユーモアのセンスがあります。 – Phil

+1

おそらくhttps://stackoverflow.com/q/4322840/11683またはhttps://stackoverflow.com/q/6174368/11683を参照してください。 – GSerg

答えて

4

あなたの基本的な問題は、新しいフォントを生成し続け、古いフォントをリリースしないことです。

setfontが呼び出されるたびに、新しいフォントを割り当てて選択します。しかし、新しいフォントをHDCに選択すると、古いフォントは決して消去されません。

SelectFontは、DeleteFontをオンにするために必要な以前に選択したフォント(ストックフォントでない限り)を返します。

さらに、GetDCコールではより大きなリソースリークがあります。getDCのMSドキュメントには、使用を完了したときにreleaseDCを使用することが示唆されています。

私の知る限り、色をリセットするためだけにフォントをリセットする必要はありません。

+0

フォントは 'SendMessage'(前のフォントを返さない)で設定されます。私が理解するように、DC部分はメトリックを計算することだけです。 – GSerg

+0

@GSergありがとうございました - いくつか編集しました – Elemental

+2

getHoverCursorが毎回新しいカーソルを作成している場合、別のリークがあるかもしれません。 –

関連する問題