Поведение глобальной переменной различается в разных функциях - PullRequest
2 голосов
/ 15 апреля 2011

Я пишу программу, которая переименовывает файл AVI (добавляет расширение - необходимо по какой-то причине), а затем получает кадр из него и сохраняет его в файле BMP.

Вот важные части кода:

#include "stdafx.h"
#include "ImageProcessor2.h"
#include <windows.h>
#include <Commdlg.h>
#include <Commctrl.h>
#include <stdio.h>
#include <string>
#include "vfw.h"
#include <atlstr.h>

// Global Variables...
HINSTANCE g_hInst;
LPSTR selectedAVI=NULL;

INT_PTR CALLBACK DialogProc(HWND, UINT, WPARAM, LPARAM);
void OpenDialog(HWND);
void GetFrame(HWND);

int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPTSTR lpCmdLine, int nCmdShow)
{
    g_hInst = hInstance;
    DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAIN), NULL,(DLGPROC)DialogProc);
    return 0;
}


INT_PTR CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch ( uMsg )
    {
        case WM_INITDIALOG:
            SetClassLongPtr(hWnd, GCLP_HICONSM, 
                (LONG_PTR)LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_IMAGEPROCESSOR2)));
            break;
        case WM_COMMAND:
            switch ( LOWORD(wParam) )
            {
                case IDCANCEL:
                    EndDialog(hWnd, LOWORD(wParam));
                    break;
                case IDB_LOADVID:
                    OpenDialog(hWnd);
                    break;
                case IDB_GETFRAME:
                    if (selectedAVI==0)
                        {
                            MessageBox(NULL, "Select the file by pressing Load button first", "Info", MB_OK);
                            break;
                        }
                    else
                    GetFrame(hWnd);
                    break;
            }
            break;
        break;
    }
    return FALSE;
}

void OpenDialog(HWND hWnd) 
{
  OPENFILENAME ofn;
  TCHAR szFile[MAX_PATH];
  char* renamedfile;

  ZeroMemory(&ofn, sizeof(ofn));
  ofn.lStructSize = sizeof(ofn);
  ofn.lpstrFile = szFile;
  ofn.lpstrFile[0] = '\0';
  ofn.hwndOwner = hWnd;
  ofn.nMaxFile = sizeof(szFile);
  ofn.lpstrFilter = TEXT("All files(*.*)\0*.*\0");
  ofn.nFilterIndex = 1;
  ofn.lpstrInitialDir = NULL;
  ofn.lpstrFileTitle = NULL;
  ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;


    if (GetOpenFileName(&ofn))
        {
            //call to rename function
            ofn.lpstrFile=renamedfile;
            MCIWndCreate(GetDlgItem(hWnd, IDC_ANIRENDER), (HINSTANCE)g_hInst,WS_CHILD|WS_VISIBLE|WS_SYSMENU|MCIWNDF_NOOPEN|MCIWNDF_NOMENU|MCIWNDF_NOTIFYALL, ofn.lpstrFile);
            selectedAVI=ofn.lpstrFile;
            SetDlgItemTextA(hWnd, IDC_EDIT1, selectedAVI);
        }
}

//rename function is here

void GetFrame(HWND hWnd)
{
    LONG hr; 
    PAVIFILE pfile;
    SetDlgItemTextA(hWnd, IDC_EDIT2, selectedAVI);

    AVIFileInit();          // opens AVIFile library 
    //further AVI processing functions are here
    AVIFileExit();          // releases AVIFile library 
}

Теперь, пожалуйста, объясните мне, почему я получаю это:

в EDIT1: правильный путь к файлу (например, «D: \ test \ testAVI.avi»)

в EDIT2: "îţîţîîţîţîîţîţî" и так далее, заканчивающиеся на "ţ ™ Öj8p"

Я думаю, что он должен показывать те же строки, потому что он читает из одной и той же глобальной переменной. Что я делаю неправильно? Как это правильно?

Спасибо

1 Ответ

3 голосов
/ 15 апреля 2011

Поскольку selectedAVI является указателем и не имеет собственного хранилища, а объект, на который он указывает (который имеет хранилище), является частью локальной переменной (структура OPENFILENAME в OpenDialog), которая к тому моменту, когда вы доберетесь до IDC_EDIT2.

, он вышел из области видимости и был перезаписан

Чтобы исправить это, измените его на массив длины MAX_PATH и используйте strcpy или аналогичный для присвоения ему. Тогда это должно работать так, как вы хотите.

...