Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Процедура генерации пароля


Автор: StillPhelix 6.1.2016, 17:46
Неработает процедура генерации пароля. Это строки 25-30.
Код

BOOL CALLBACK CrDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    char buffer[] = "";
    HWND hEditBox;
    WORD twoChar;
    unsigned char ch;
    char calcCode[] = "";
    char userInputCode[] = "";
    int lenText;
    
    switch (uMsg)
    {
    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case IDOK:
            hEditBox = GetDlgItem(hDlg, IDC_USER_NAME);
            lenText=Edit_GetTextLength(hEditBox);
            GetWindowText(hEditBox, buffer, lenText+1);
            if ((GetWindowTextLength(hEditBox)+1)<0xA)
            {
                MessageBox(hDlg, "Your name too short!", "Error", MB_OK | MB_ICONSTOP);
                return false;
            }
            for (int i = 0; i<lenText+1; i++)
            {
                twoChar = (WORD)buffer[i]*buffer[i+1];//при пошаговом прохождении это пропускается
                ch=twoChar % 0x20 + 'A';//при пошаговом прохождении это пропускается
                calcCode[i]=ch;//А тут что-то делается. Что тут можно накопить, если предыдущие 2 строки пропущены
            }

            hEditBox = GetDlgItem(hDlg, IDC_EDIT1);
            lenText=Edit_GetTextLength(hEditBox);
            GetWindowText(hEditBox, userInputCode, lenText+1);
            if (calcCode == userInputCode)
            {
                MessageBox(hDlg, "Password OK.", "Info", MB_OK | MB_ICONASTERISK);
                return false;
            } 
            else
            {
                MessageBox(hDlg, "Wrong Password!", "Error", MB_OK | MB_ICONSTOP);
                SendMessage(hEditBox, EM_SETSEL, 0, -1);
            }
            break;

        case IDCANCEL:
            EndDialog(hDlg, 0);
            return true;
        }
        break;
    }
    return false;
}

Автор: feodorv 6.1.2016, 19:19
Цитата(StillPhelix @  6.1.2016,  17:46 Найти цитируемый пост)
Неработает процедура генерации пароля.

В каком смысле "не работает"?


Цитата(StillPhelix @  6.1.2016,  17:46 Найти цитируемый пост)
//А тут что-то делается. Что тут можно накопить, если предыдущие 2 строки пропущены

Наверняка Вы компилите с оптимизацией, тогда Ваши три строки просто эквивалентны одной:
Код
                calcCode[i]= ((WORD)buffer[i]*buffer[i+1]) % 0x20 + 'A';
Вряд ли в ней делается что-то не то, всё должно вычисляться, но да, оптимизация съела две первые строки (которые Вы и не видите при пошаговом просмотре), дело обычное.


Замечания по коду.

Цитата(StillPhelix @  6.1.2016,  17:46 Найти цитируемый пост)
            for (int i = 0; i<lenText+1; i++)
Здесь очень нехороший +1, так как ниже идёт обращение к buffer[i+1], что даёт выход за пределы строки (на один байт после '\0').


Цитата(StillPhelix @  6.1.2016,  17:46 Найти цитируемый пост)
   char buffer[] = "";
Такой подход - это просто безобразие. Как Вы думаете, сколько байт выделено под буфер? (И обязана ли эта память быть доступной на запись?) Ниже совершенно безосновательно считается, что буфер вмещает как минимум lenText+1 байт, что совершенно не верно. То же касается массивов calcCode и userInputCode.


Цитата(StillPhelix @  6.1.2016,  17:46 Найти цитируемый пост)
          lenText=Edit_GetTextLength(hEditBox);
            GetWindowText(hEditBox, buffer, lenText+1);
            if ((GetWindowTextLength(hEditBox)+1)<0xA)
Чему верить, Edit_GetTextLength(hEditBox) или GetWindowTextLength(hEditBox)? И если это одно и тоже, то зачем тогда оно два раза?

Добавлено через 8 минут и 20 секунд
Цитата(StillPhelix @  6.1.2016,  17:46 Найти цитируемый пост)
            if (calcCode == userInputCode)
Так строки не сравниваются. Так сравниваются указатели (которые, очевидно, различные).

Автор: StillPhelix 6.1.2016, 20:05
Цитата

В каком смысле "не работает"?

Не заполняется массив calcCode[i]
Цитата

Такой подход - это просто безобразие. Как Вы думаете, сколько байт выделено под буфер? (И обязана ли эта память быть доступной на запись?) Ниже совершенно безосновательно считается, что буфер вмещает как минимум lenText+1 байт, что совершенно не верно. То же касается массивов calcCode и userInputCode.

Буфер должен быть динамическим. Неизвестно, сколько символов будет введено в TextEdit. Как правильно определить/установить его размер?
Цитата

Так строки не сравниваются. Так сравниваются указатели (которые, очевидно, различные).

strcmp не работает тоже.
а после 
Код

GetWindowText(hEditBox, userInputCode, lenText+1);

это строка 34, заполняются все массивы. этого не должно быть.

Автор: StillPhelix 6.1.2016, 20:30
Исправил. Текст ниже. Теперь цикл генератора 
Код

for (int i = 0; i<lenText; i++)
 заполняет почему-то все буферы (наверно не правильно определил размер), а 
Код

GetWindowText(hEditBox, userInputCode, lenText+1);
 не копирует текст из поля в буфер. И не вызывается MessageBox.
Код

BOOL CALLBACK CrDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    
    char buffer[] = "";
    HWND hEditBox;
    WORD twoChar;
    unsigned char ch;
    char calcCode[] = "";
    char userInputCode[] = "";
    int lenText;
    
    switch (uMsg)
    {
    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case IDOK:
            hEditBox = GetDlgItem(hDlg, IDC_USER_NAME);
            lenText = Edit_GetTextLength(hEditBox);
            GetWindowText(hEditBox, buffer, lenText+1);
            if ((lenText+1)<0xA)
            {
                MessageBox(hDlg, "Your name too short!", "Error", MB_OK | MB_ICONSTOP);
                return false;
            }
            for (int i = 0; i<lenText; i++)
            {
                twoChar = buffer[i]*buffer[i+1];
                ch = twoChar % 0x20 + 'A';
                calcCode[i] = ch;
            }

            hEditBox = GetDlgItem(hDlg, IDC_EDIT1);
            lenText=Edit_GetTextLength(hEditBox);
            GetWindowText(hEditBox, userInputCode, lenText+1);
            if (strcmp(calcCode,userInputCode))
            {
                MessageBox(hDlg, "Password OK.", "Info", MB_OK | MB_ICONASTERISK);
                return false;
            } 
            else
            {
                MessageBox(hDlg, "Wrong Password!", "Error", MB_OK | MB_ICONSTOP);
                SendMessage(hEditBox, EM_SETSEL, 0, -1);
            }
            break;

        case IDCANCEL:
            EndDialog(hDlg, 0);
            return true;
        }
        break;
    }
    return false;
}

Автор: StillPhelix 6.1.2016, 21:17
Рабочий код (не работает только 
Код

SendMessage(hEditBox, EM_SETSEL, 0, -1);
Почему?):
Код

BOOL CALLBACK CrDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    
    char buffer[MAX_LEN] = "";
    HWND hEditBox;
    WORD twoChar;
    unsigned char ch;
    char calcCode[MAX_LEN] = "";
    char userInputCode[MAX_LEN] = "";
    int lenText;
    
    switch (uMsg)
    {
    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case IDOK:
            hEditBox = GetDlgItem(hDlg, IDC_USER_NAME);
            lenText = Edit_GetTextLength(hEditBox);
            GetWindowText(hEditBox, buffer, lenText+1);
            if ((lenText+1)<0xA)
            {
                MessageBox(hDlg, "Your name too short!", "Error", MB_OK | MB_ICONSTOP);
                return false;
            }
            for (int i = 0; i<lenText; i++)
            {
                twoChar = buffer[i]*buffer[i+1];
                ch = twoChar % 0x20 + 'A';
                calcCode[i] = ch;
            }

            hEditBox = GetDlgItem(hDlg, IDC_EDIT1);
            lenText=Edit_GetTextLength(hEditBox);
            GetWindowText(hEditBox, userInputCode, lenText+1);
            if (strcmp(calcCode,userInputCode))
            {
                MessageBox(hDlg, "Wrong Password!", "Error", MB_OK | MB_ICONSTOP);
                SendMessage(hEditBox, EM_SETSEL, 0, -1);
            } 
            else
            {
                MessageBox(hDlg, "Password OK.", "Info", MB_OK | MB_ICONASTERISK);
                return false;
            }
            break;

        case IDCANCEL:
            EndDialog(hDlg, 0);
            return true;
        }
        break;
    }
    return false;
}

Автор: feodorv 7.1.2016, 11:15
Цитата(StillPhelix @  6.1.2016,  21:17 Найти цитируемый пост)
не работает только

А что именно Вы хотите сделать? Приведённый код выделяет весь текст в редакторе.

Автор: StillPhelix 7.1.2016, 18:32
Цитата

А что именно Вы хотите сделать? Приведённый код выделяет весь текст в редакторе.

В этой программе EM_SETSEL ничего делать не будет. Для того, чтобы это сообщение что-то сделало, нужно элементу управления дать фокус. Что я и сделал. Теперь всё работает. 

Автор: feodorv 8.1.2016, 11:05
Цитата(StillPhelix @  7.1.2016,  18:32 Найти цитируемый пост)
В этой программе EM_SETSEL ничего делать не будет. Для того, чтобы это сообщение что-то сделало, нужно элементу управления дать фокус. Что я и сделал. Теперь всё работает.  

EM_SETSEL прекрасно работает (то есть устанавливаются начальный и конечный символы выделения, каретка передвигается за конечный символ выделения, текст при необходимости скролируется так, чтобы каретка стала видна), просто сам контрол перерисовывается, если уже имеет фокус, или в момент получения фокуса, это да.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)