Мои условия возвращают false, даже если они должны возвращать true - PullRequest
0 голосов
/ 25 апреля 2020

Я пытаюсь проверить длину строки в моем буфере обмена, а также первый символ строки, и если она возвращает значение true, я хотел бы установить для буфера обмена другое содержимое. Вот мой класс;

#include <iostream>
#include <windows.h>
#include <cstring>

namespace Diall_ClipBoard_catch
{
    class ClipBoard
    {
    private:
        ::HANDLE dHDat;
        ::std::string tmpstringsign;
        bool isopen;
        char* dHbuffer;
        char* dHbuffertemp;
        char* dNtoken;
    public:
        ClipBoard(void)
        {
            this->dHbuffer = const_cast <char*>("");
            this->dHbuffertemp = const_cast <char*>("");
            this->tmpstringsign = "dnb_4554_2102";
            this->isopen = false;
        };
        ~ClipBoard(void)
        {

        }
        char* GetData(void)
        {
            this->Start();
            if (this->isopen)
            {
                this->dHDat = ::GetClipboardData(CF_TEXT);

                if (this->dHDat)
                {
                    this->dHbuffer = (char*)::GlobalLock(this->dHDat);

                    if (::std::strcmp(this->dHbuffertemp, this->dHbuffer) != 0 && this->dHbuffer != "" && this->dHbuffer != NULL)
                    {
                        this->dHbuffertemp = this->dHbuffer;
                        //::std::cout << this->dHbuffer << "\n";
                        return this->dHbuffer;
                    }

                    ::GlobalUnlock(this->dHDat);
                }
                CloseClipboard();
                this->isopen = FALSE;
                ::Sleep(1000);
            }
        }
        void SetData(void)
        {
            const char* data = this->dHbuffer;
            const char* newstring = "Hello World";
            const size_t len = strlen(newstring) + 1;
            HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len);
            memcpy(GlobalLock(hMem), newstring, len);
            GlobalUnlock(hMem);
            if (!OpenClipboard(NULL))
            {
                return;
            }
            if (strlen(data) == 8)
            {
                    if(data[0] == '1' || data[0] == '7')
                    {
                        EmptyClipboard();
                        SetClipboardData(CF_TEXT, hMem);
                    }
            }
            CloseClipboard();
            this->isopen = TRUE;
        }
    private:
        void Start(void)
        {
            if (!OpenClipboard(NULL))
            {
                return;
            }
            this->isopen = true;
        }
    };
}

А вот мой главный. cpp

#include "Clipboard.h"

int main()
{
    ::Diall_ClipBoard_catch::ClipBoard* clipboard = new Diall_ClipBoard_catch::ClipBoard();
    int temp1 = 0, temp2 = 0;
    EmptyClipboard();
    while (1)
    {
        temp1 = GetClipboardSequenceNumber();
        if (temp1!= temp2)
        {
            clipboard->SetData();
            std::cout << clipboard->GetData() << std::endl;
        }

        temp2 = temp1;
    }
    return 0;
}

Когда я пытаюсь отобразить strlen (данные), полученное значение равно 0, которое должно не будет дела. Но я получаю первый символ строки из data [0], но когда я проверяю его по своему условию, он всегда возвращает false, даже если он должен возвращаться как true.

PS. Я абсолютный новичок в C ++.

Ответы [ 2 ]

0 голосов
/ 25 апреля 2020

В

           this->dHDat = ::GetClipboardData(CF_TEXT);

           if (this->dHDat)
           {
               this->dHbuffer = (char*)::GlobalLock(this->dHDat);

               if (::std::strcmp(this->dHbuffertemp, this->dHbuffer) != 0 && this->dHbuffer != "" && this->dHbuffer != NULL)
               {
                   this->dHbuffertemp = this->dHbuffer;
                   //::std::cout << this->dHbuffer << "\n";
                   return this->dHbuffer;

вы не копируете данные, но сохраняете (энергозависимый) указатель в char *, вам необходимо дублировать его из документации по функции GetClipboardData :

Приложение должно немедленно скопировать данные.

Почему вы используете массив char? Вы находитесь на C ++, используйте std::string

[редактировать для вашего замечания]

используя std::string первая часть вашего кода становится (я не вижу использования dNtoken , поэтому я оставил его без изменений):

#include <iostream>
#include <windows.h>
#include <string>

namespace Diall_ClipBoard_catch
{
    class ClipBoard
    {
    private:
        ::HANDLE dHDat;
        ::std::string tmpstringsign;
        bool isopen;
        std::string dHbuffer;
        std::string dHbuffertemp;
        char* dNtoken;
    public:
        ClipBoard(void)
        {
            tmpstringsign = "dnb_4554_2102";
            isopen = false;
            dNtoken = NULL; // better to not let it non initialized
        };
        ~ClipBoard(void)
        {
            // if needed free(dNtoken)
        }
        std::string GetData(void)
        {
            this->Start();
            if (this->isopen)
            {
                this->dHDat = ::GetClipboardData(CF_TEXT);

                if (this->dHDat)
                {
                    this->dHbuffer = (char*)::GlobalLock(this->dHDat);

                    if ((this->dHbuffertemp != this->dHbuffer) && !this->dHbuffer.empty())
                    {
                        this->dHbuffertemp = this->dHbuffer;
                        //::std::cout << this->dHbuffer << "\n";
                        return this->dHbuffer;
                    }

                    ::GlobalUnlock(this->dHDat);
                }
                CloseClipboard();
                this->isopen = FALSE;
                ::Sleep(1000);
            }
        }
        void SetData(void)
        {
            std::string data = this->dHbuffer;
            const char* newstring = "Hello World";
            const size_t len = strlen(newstring) + 1;
            HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len);
            memcpy(GlobalLock(hMem), newstring, len);
            GlobalUnlock(hMem);
            if (!OpenClipboard(NULL))
            {
                return;
            }
            if (data.length() == 8)
            {
                    if(data[0] == '1' || data[0] == '7')
                    {
                        EmptyClipboard();
                        SetClipboardData(CF_TEXT, hMem);
                    }
            }
            CloseClipboard();
            this->isopen = TRUE;
        }
    private:
        void Start(void)
        {
            if (!OpenClipboard(NULL))
            {
                return;
            }
            this->isopen = true;
        }
    };
}

Дополнительное примечание, вам не нужно писать this-> во всем коде выше

0 голосов
/ 25 апреля 2020

dHbuffer инициализируется для указания на ""

В SetData вы присваиваете data значение dhBuffer, которое указывает на ""

Затем вы делаете strlen(data), он же strlen(""), который имеет длину 0.

Советы всех остальных довольно solid. Неясно, кем вы «были», когда у вас возникла проблема, и вам, вероятно, следует использовать std::string.

...