本文介绍了围绕可变字符串的堆栈已损坏C ++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好!

我用于枚举Childwindows的类有问题.
我时不时地得到变量"String"周围的堆栈已损坏".
通常,当您超出"某些向量或数组的范围时会触发此类消息..但是我找不到错误.

如果这里有人要测试该课程,则代码如下:

Hello out there!

I have a problem with a class I use to enumerate Childwindows.
Every now and then i get "Stack around the variable ''String'' was corrupted".
Usually this kind of message is triggered when you are "out of bounds" of some vector or array....but I can not find the error.

If someone here wants to test this class, here is the code:

#include "TChar.h"
#include "string.h"
#include "windows.h"
#include "Winuser.h"
#include <string>
#include <vector>

using namespace std;

typedef std::basic_string<TCHAR> tstring;


class ChildHandles
{

public:
    struct child_data
    {
        tstring caption;
        HWND handle;
		tstring ClassName;
		RECT windowrect;
    };


private:
    std::vector<child_data> stuff;

    BOOL add_window(HWND hwnd)
    {
        TCHAR String[300] = {0};
        if (!hwnd)
            return TRUE;
        if (!::IsWindowVisible(hwnd))
            return TRUE;
        LRESULT result = SendMessageW(hwnd, WM_GETTEXT, sizeof(String), (LPARAM)String);
            return TRUE;

		child_data data;

///////////////////////////////////////////////////////////////////////////////////

			for(int i = 0; i < sizeof(String)/8; i++)
            data.caption.push_back(String[i]);

///////////////////////////////////////////////////////////////////////////////////

		TCHAR buffer[30];
		GetClassName(hwnd,buffer,sizeof(buffer));
		for(int i = 0; i < sizeof(buffer)/4; i++)
            data.ClassName.push_back(buffer[i]);
///////////////////////////////////////////////////////////////////////////////////
		RECT childwindow;
		RECT * pchildwindow;
		pchildwindow  = &childwindow;
		int checkmain = GetWindowRect(hwnd,pchildwindow);
		if(checkmain=0)
        {
            // Error! Call GetLastError();
        }

///////////////////////////////////////////////////////////////////////////////////

        data.handle = hwnd;
        stuff.push_back(data);
        return TRUE;
    }



    static BOOL CALLBACK EnumWindows(HWND hwnd, LPARAM lParam)
    {
        ChildHandles* ptr = reinterpret_cast<ChildHandles*>(lParam);
        return ptr->add_window(hwnd);
    }

public:
    ChildHandles& enum_windows(HWND hParentWnd)
    {
        stuff.clear();                                  //clean up
        if(!EnumChildWindows(hParentWnd, EnumWindows, reinterpret_cast<LPARAM>(this)))
        {
            // Error! Call GetLastError();
        }
        return *this;
    }

    std::vector<child_data>& get_results()
    {
        return stuff;
    }

};



其调用方式为:



Its called using:

std::vector<ChildHandles::child_data> ChildWindows = ChildHandles().enum_windows(htablehandle).get_results();



我正在使用Visual Studio....感谢您提供任何提示,帮助或解决方案...

:doh:



I am using Visual Studio.... Thanks for any hints, help or solutions...

:doh:

推荐答案

BOOL add_window(HWND hwnd) {
	TCHAR String[300] = {0};
	if (!hwnd) {
		return TRUE;
	}
	if (!::IsWindowVisible(hwnd)) {
		return TRUE;
	}
	//You should not use functions with W or A at the end unless you are specifically using that type of string. The macros will automatically choose the right function for your character set.
	LRESULT result = SendMessage(hwnd, WM_GETTEXT, ARRAYSIZE(String), (LPARAM)String);
	//Check the return value of SendMessage. That is the number of chars written, not including the NULL. If it is more than 299 we have a problem
	if (result >= ARRAYSIZE(String)) {
		MessageBox(NULL, TEXT("Too many characters were copied into the buffer"), TEXT("Buffer overflow"), MB_OK); //You should insert a breakpoint on this line to see what is hapening if it gets hit.
	}
	return TRUE; //What is this? This will stop executing here and skip the rest of the function.
	child_data data;
	///////////////////////////////////////////////////////////////////////////////////
	for(int i = 0; i < sizeof(String) / 8; i++) { //Be carefukl here... sizeof(String) = 2x the length of the string in String. Did you mean to use ARRAYSIZE()?
		data.caption.push_back(String[i]);
	}
	///////////////////////////////////////////////////////////////////////////////////
	TCHAR buffer[30];
	GetClassName(hwnd, buffer, ARRAYSIZE(buffer));
	for(int i = 0; i < sizeof(buffer) / 4; i++) { //Again, be carefukl here... sizeof(buffer) = 2x the length of the string in buffer. Did you mean to use ARRAYSIZE()?
		data.ClassName.push_back(buffer[i]);
	}
	///////////////////////////////////////////////////////////////////////////////////
	RECT childwindow;
	//These 3 lines can br replaced with a single line
	//RECT *pchildwindow;
	//pchildwindow  = &childwindow;
	//int checkmain = GetWindowRect(hwnd, pchildwindow);
	int checkmain = GetWindowRect(hwnd, &childwindow);
	if (checkmain = 0) {
		//Error! Call GetLastError();
		//This doesn''t tend to happen when you check hwnd != NULL && IsWindow(hwnd)
	}
	///////////////////////////////////////////////////////////////////////////////////
	data.handle = hwnd;
	stuff.push_back(data);
	return TRUE;
}




这篇关于围绕可变字符串的堆栈已损坏C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 08:45
查看更多