-1

我一直在尝试做一些据说很简单的事情,但像往常一样,在可疑的情况下,它对我不起作用。我想要做的只是将位图加载到屏幕并保持在那里。(弹出)窗口将没有控件,无法移动,并且只会通过它的泵处理 WM_PAINT;就像一个闪屏。

代码在调试模式下编译良好并且运行良好,但是当我切换到发布模式时 LoadImage()总是返回NULL,结果其他一切都失败了。这是我在这种方法上花费的第四个小时,我认为是时候寻求帮助了。我已经检查了未初始化的内存,并且可以确保使用的每个类成员都初始化为0,并且有理由确定这不是问题。我将在下面发布代码,非常感谢您的帮助。

如果可能的话,我宁愿只使用 WinAPI 执行此操作,因为我不会在此应用程序的其他任何地方使用此功能。当然,我仍然对想法持开放态度,但很可能我只是犯了一个愚蠢的错误。再次,谢谢!


int CreateWindowWithUserFormat()
{   
    SIZE BMSize = {0};
    LoadedBitmap = (HBITMAP) LoadImage(NULL,
    L"Art\\Splash_Screens\\1.bmp", IMAGE_BITMAP,
    NULL, NULL, LR_LOADFROMFILE);

    if(!LoadedBitmap) {
    MessageBox(NULL,
        L"Error loading image to void * HBITMAP",
        L"Error Loading Splash", NULL);
    }

    ScreenDevCtxt = CreateCompatibleDC(NULL);
    if(!ScreenDevCtxt) {
    //Failure
    }

    ReplacedObject = SelectObject(ScreenDevCtxt, (HGDIOBJ) LoadedBitmap);
    if(ReplacedObject == NULL || ReplacedObject == HGDI_ERROR) {
    //Failure
    }

    if( (!GetBitmapDimensionEx(LoadedBitmap, &BMSize) ) ||
    BMSize.cx == 0 || BMSize.cy == 0) {
    //Failure, try alternate:
        BITMAP Bm = {0};
    if( (!GetObject(LoadedBitmap, sizeof(Bm), &Bm) ) ||
        Bm.bmWidth == 0 || Bm.bmHeight == 0) {

    MessageBox(NULL,
        L"Error getting bitmap size; loading aborted.",
        L"Error Loading Splash Image", NULL); 
    }
    // Alternate success; use these as size.
    BMSize.cx = Bm.bmWidth;
    BMSize.cy = Bm.bmHeight;
    }

    {
    RECT WindowSize = {0};
    WinHelper.CenterRectInScreen(WindowSize, BMSize.cx, BMSize.cy);

    if(!Create(L"TitleName",
        WS_POPUPWINDOW | WS_EX_TOPMOST,
        WS_EX_TRANSPARENT,
        WindowSize.left, WindowSize.top,
        WindowSize.right, WindowSize.bottom,
        NULL, NULL) )
    {
        return false;
    }
    return true;
    }
}

可能值得一提的是,它在它自己的线程上运行。线程包装器负责在收到来自应用程序的信号并且经过一定时间(我相信是 5 秒)后销毁此窗口。我有理由确定这不是问题的根源,但谁知道呢?我没主意了。问题只出现在发布模式,是的,发布模式仍然可以访问文件(Art\\Splash_Screens\\1.bmp)。我能做些什么来解决这个问题?

更新 好吧,在这之后只花了几分钟就意识到路径是错误的......我仍然不知道为什么,但如果我们取出中间文件夹并"1.bmp"直接贴在可执行文件旁边,显然它工作正常。感谢你们。

4

2 回答 2

1

很多时候,我注意到这样的问题与路径有关。请注意,发布可执行文件的位置并不重要,重要的是“当前工作目录”是什么。

getcwd您可以使用or(在 Win32 中)GetCurrentDirectory函数调用来获取当前工作目录。

作为附加测试,为了确保文件确实在您认为的位置(相对于您的 CWD),我会打个fopen(..., "r")电话,并检查它是否成功。

于 2013-04-28T22:27:34.040 回答
0

当您从 IDE 执行应用程序时,工作目录就是您的项目目录。但是当您作为调试/发布版本发布时,您的 IDE 会将您的应用程序放入文件夹 projectfolder/bin/debug(release) 中。现在它的工作目录不是你的 projectfolder 而是 projectfolder/bin/debug(release)。这就是为什么它会在 IDE 中运行时找到您的位图,但在作为调试/发布版本发布后却没有。

您可以执行以下操作:

位图的路径例如是“yourProjectFolder/image/bitmap1.bmp”。您可以在 IDE 中运行 -> 没问题。您的代码如下所示:

LoadedBitmap = (HBITMAP)LoadImage(NULL,
               "image/bitmap1.bmp", IMAGE_BITMAP,
               NULL, NULL, LR_LOADFROMFILE);

现在你想作为调试发布。工作目录现在是 projectfolder/bin/debug,因此将搜索路径更改为:

LoadedBitmap = (HBITMAP)LoadImage(NULL,
               "../../image/bitmap1.bmp", IMAGE_BITMAP,
               NULL, NULL, LR_LOADFROMFILE);

对于每个 ../,IDE 将升级一个文件夹级别。这意味着从这里:projectFolder/bin/debug 到这里:projectfolder/image 机器必须向上执行两次,直到它到达 projectfolder 加上 /image 为你的图像文件夹。所以 ../../image 会导致 bin/debug 中的 projectfolder/image。

但这是一种解决方法!最好从资源中加载图像。

于 2016-03-24T12:03:10.347 回答